OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4057|回复: 3

C语言变量的梳理---static/extern

[复制链接]

19

主题

49

帖子

0

精华

高级会员

Rank: 4

积分
728
金钱
728
注册时间
2015-8-20
在线时间
58 小时
发表于 2020-3-26 01:14:33 | 显示全部楼层 |阅读模式
武汉疫情,在家学习原子哥的linux视频.......
闲时,想梳理下C语言几个易错的知识点。
1.  static的用法
C语言中static的用法只有两种:修饰变量、修饰函数
1.1  static修饰变量
static修饰变量分为两中情况:
a情况:static 修饰 局部变量
b情况:static 修饰 全局变量
static在这这两种情形下的使用时,其结果不能用类比的方式去看待的。
1.1.1  static修饰局部变量
int main_func1(int x)
{
    static int tmp1=1;
    tmp1++;
    printf("main_func1 runs,tmp1 = %d \r\n",tmp1);
    return x;
}

main_func1函数第一次被调用时tmp1=1(变量声明被赋初值1) -->tmp1=1+1=2 --> return
main_func1函数下一次被调用时tmp1(上次的值未被释放)----->tmp1=2+1=3 --> return
重要结论:static修饰的局部变量,在该变量所在函数调用结束后,该变量的值不释放,
                下次调用时该变量的初值为上次调用结束时的值。
1.1.2  static修饰全部变量
如果要通过实验来观察static所修饰的全局变量,需要至少两个.c文件,在一个文件中定义static int lib1_arg1;
并在这个文件中被一个函数所调用(应该是修改)。
通过实验可知,static修饰的全局便令的值在函数调用后,仍会保留。
                      static修饰全局变量只对该文件中可见,其他文件不可见。
                  (其它文件无法引用该变量;可以定义一个与之同名的变量,但两个变量之间并无关系)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
那这里又有一个问题,如果如果两个文件之间共用一个变量,该怎么办呢?
可以在a.c文件中定义一个全局变量 int arg1,在需要引用这个变量的文件中声明extern int arg1,这样这两个文件就共用了变量arg1。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.2  static修饰函数
static修饰函数和static修饰全局变量类似,表示该函数只对其所在的文件可见。
这么做是为什么呢?
比如:我在lib1.c中定义了n个函数,其中有一个函数base_func(void),被其他n-1个函数中的某几个调用(因此这个函数有存在的必要),同时我又不想别人在其他文件中调用这个函数(主要是我怕这个函数和别人定义的函数重名,所以不希望别人调用这个函数),那么我在声明和定义这个函数时用static修饰这个函数即可。
重要结论:static修饰函数,则该函数只对本文件可见,对其他文件不可见。
---------------------------------------------------------------------------------------------
又有一个问题,如果我包含了别人的.h文件,自然我可以调用别人.c文件中定义的函数,比如int xxx_func(int),
那我可不可以在我的.c文件中定义一个static int xxx_func(int)函数呢?
答:显然是不行的。如果这么做可以,那我在我的.c文件中的其他函数中调用int xxx_func(int),那该函数该怎么执行呢?
------------------------------------------------------------------------------------------------------------------------------------------


2.  extern的用法
2.1  extern修饰变量
上面说完了static的用法,与static对应则是extern。
通过对static的梳理,我们知道,static修饰的全局变量,只对其所在的文件可见。
如果不用static修饰的变量是不是就是说该变量对其他文件是可见的呢?
答案是肯定的,如果在a.c文件中定义了一个全局变量int arg_abs(注意是全局变量,所谓全局变量就是指它在整个工程全局中是可见的),那么如果想要在b.c中去引用这个arg_abs,如果不声明这个变量是外部已经定义过的全局变量,那么b.c这个文件就会认为arg_abs是为被定义的变量。因此只能在b.c文件中声明该变量为extern int arg_abs,这样编译器就会从另外的声明了arg_abs的文件中引用这个变量。
结论:如果想让某个全局变量只对本文件可见,则需要在声明时用static修饰,如果不用static修饰,则其他文件通过extern修饰后,可以引用该变量。
2.2  extern修饰函数
函数从本质上来说和变量是一样的,extern修饰的函数,表明该函数在别的文件中定义过了,因此可以调用该函数。
这里似乎有个问题,本来我在a.c文件中要调用x.c文件中定义的函数,我就会在a.c的头文件中包含x.h,那我还需要extern干什么呢?
嗯,是的,如果用a.c--包含x.h;--x.c定义函数--这种模式,完全就不需要用extern去修饰所调用的函数。但extern给了我们一种不用编写x.h(或者说不用包含x.h),而直接在使用函数前,利用extern去修饰该函数,在调用函数的方式。但总的说来这种这种方式容易出现函数重复命名的错误,不建议使用。





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

890

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2390
金钱
2390
注册时间
2019-9-25
在线时间
397 小时
发表于 2020-3-26 10:34:43 | 显示全部楼层
回复 支持 反对

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2178
金钱
2178
注册时间
2018-8-27
在线时间
258 小时
发表于 2020-3-26 13:08:31 | 显示全部楼层
可以  可以!
森罗万象
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-3-10
在线时间
13 小时
发表于 2020-4-7 11:31:59 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 10:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表