文档章节

C语言中static extern的使用

o
 osc_wws45aot
发布于 2019/08/20 21:56
字数 1267
阅读 9
收藏 0

10:30:22 2019-08-20

基础不牢 瞬间爆炸

 

参考资料:https://blog.csdn.net/ts_54eagle/article/details/4418627

https://blog.csdn.net/xingjiarong/article/details/47656339

https://blog.csdn.net/xingjiarong/article/details/47656339

看看C Primer Plus上是怎么定义的

先说说作用域 分为4种:块作用域 函数作用域 函数原型作用域 文件作用域

这里要说明的是 块作用域指{}之间的部分

而函数作用域单单指goto标签   当goto标签出现在函数内部时 goto标签作用域蔓延至整个函数

函数原型作用域从形参定义到原型声明结束为止

文件作用域指的是 该文件 该文件 该文件  从变量定义到文件末尾都可见

 

链接分为3种:外部链接 内部链接 无链接  (决定了是否能被外部文件使用)

块作用域 函数作用域 函数原型作用域的变量 都属于无链接

文件作用域的变量  可以属于外部链接 也可属于内部链接

 

内部链接的文件作用域 称为 文件作用域(只能在该文件内部使用)

外部链接的文件作用域 称为 全局作用域(整个程序都可使用)

一个具有文件作用域的变量默认是具有全局作用域的   在前面加上static变为具有文件作用域

 

C对象有4种存储期:静态存储期、线程存储期、自动存储期、动态分配存储期。 

如果某个变量具有静态存储期,该变量在程序运行过程中一直存在   文件作用域具有静态存储期

在具有文件作用域的变量前加上static 表示该变量的作用域限制为内部链接

对于所有的具有文件作用域的变量(无论它具有内部链接还是外部链接)都具有静态存储期  而声明了static的文件作用域的变量具有内部链接

 

存储类别 存储期 作用域 链接 声明方式
自动 自动 块内
寄存器 自动 块内 使用关键字register
静态外部链接 静态 文件 外部 所有函数外
静态内部链接 静态 文件 内部 所有函数外 使用关键字register
静态无链接 静态 块内 使用关键字register

 

 

 

 

 

 

auto: 默认情况下 声明在块内和函数头中的变量都是auto类型的变量   也可以显式的在变量声明时写上auto auto变量在使用时在栈上申请空间 使用结束后自动销毁

register:寄存器变量存储在寄存器中

 

static:对于局部变量来说 声明为static 在使用时只会声明一次  之后不会再声明 对变量的改变会被保存(对它进行改变是在定义改变量的块中 或者通过变量的指针)这样改 局部变量具有了静态存储期

对于外部变量(具有文件作用域的变量)来说 static会将该变量声明为内部链接

extern:用extern声明 表明变量定义在别处  (extern也是声明 是引用性声明 不是定义性声明)

在使用另外一个文件中的全局变量时要用extern声明   这让人有些迷惑 前面说 声明为外部变量(未加static)具有全局作用域 那不就是能被其它文件使用了吗  这样的想法是错误的

c primer puls解释的很清楚 :如果外部变量定义在一个文件中,那么其它文件在在使用该变量前必须先声明它(用extern声明)。也就是说,在某文件中对外部变量进行定义式声明只是单方面允许其它文件使用改变量,其它文件在用extern声明之前不能直接使用它

 

对于自动变量来说 未初始化 它中的数据是垃圾

对于具有静态生存期的变量来说 如果未初始化 它里面的数据为0

 

例子:

main.c

 1 #include <stdio.h>
 2  void fun();
 3 int main()
 4 {
 5    fun();
 6    fun();
 7     return 0;
 8  }
 9 void fun()
10 {
11     int num2=5;
12     static int num1;
13     printf("num1 is:%d\n",num1);
14     printf("num2 is:%d\n",num2);
15     num1++;
16     num2++;
17 }

输出结果:

可以看到 num1保存了上次的值

 

 1 //file1.c
 2 int num1=1;
 3 static int num2=2;
 4 
 5 //file.c
 6 #include <stdio.h>
 7 extern int num1;
 8 extern int num2;    //这句话只是说明num2是定义在另一个文件中的 但num2是不具有外部
 9                             //链接的 所以下面是无法使用的
10 int main()
11 {
12     printf("%d",num1);
13     //printf("%d",num2);    //这句话是错的 
14     return 0;
15 }

 

 1 //file1.c
 2 #include<stdio.h>
 3 void fun()
 4 {
 5     printf("fun()");
 6 }
 7 
 8 //file2.c
 9 #include <stdio.h>
10 extern void fun();
11 int main()
12 {
13     fun();
14     return 0;
15 }

extern也可以对函数进行引用式声明

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

李开复谈2020年AI科学家创业。道翰天琼认知智能api机器人接口。

2012年至今,在深度学习推动下,这一波人工智能的蓬勃发展已进入第十个年头。 在初期,一系列由AI科学家创建的初创公司,经过大浪淘沙,如今已有多家脱颖而出成为独角兽企业;榜样在先,于是...

jackli2020
15分钟前
9
0
什么是PHP中的线程安全或非线程安全? - What is thread safe or non-thread safe in PHP?

问题: I saw different binaries for PHP, like non-thread or thread safe? 我看到了PHP的不同二进制文件,例如非线程还是线程安全的? What does this mean? 这是什么意思? What is the ...

fyin1314
28分钟前
26
0
移动社交如何玩?网易云信携手崽崽和Uki打造更多新场景!

随着95后、00后为主的年轻一代逐渐成为中国移动社交下的主力军,社交需求也发生了一些变化。这些年轻用户更倾向于有趣好玩,形式多样化的社交方式。同时也产生了如“扩列”、“养火花”等众多...

真正稳定的网易云信
35分钟前
22
0
如何在Java代码中去掉烦人的“!=null”

问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc();} 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥...

码农突围
35分钟前
21
0
ELK使用容器集成安装

ELK使用容器集成安装 1. 查看集成ELK:sebp docker search sebp 2. 设置内核参数 sysctl -w vm.max_map_count=262144 3. 拉取sebp/elk docker pull sebp/elk 4. 运行ELK yum install -y java......

huanke
45分钟前
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部