高级会员
- 积分
- 728
- 金钱
- 728
- 注册时间
- 2015-8-20
- 在线时间
- 58 小时
|
武汉疫情,在家学习原子哥的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去修饰该函数,在调用函数的方式。但总的说来这种这种方式容易出现函数重复命名的错误,不建议使用。
|
|