C语言 static 声明静态变量?大佬原来用它干这事!
为什么要说这个?其实就是因为 关键字,有一个功能,就是会让局部变量本该在栈上,用这个声明后,就会进入全局区域,也就是从栈区域,进入到数据区域。
下面我们来看下代码:add.c
hello.c
我们这里看下,没有# “add.h”, 我们使用
gcc -o add.o -c add.c
gcc -o hello.o -c hello.c
gcc -o hello hello.o add.o
发现是可以编译过,也能链接过,也能运行。我们使用 -s add.o ,看到信息,add前面有个Bind的值是,这个就是说明,add是在可以让其他.o链接时候去查找的一个符号,它的类型是func函数。
然后我们把add.c 改成这个:(前面加上一个)
编译链接就会失败,找不到add方法,那么我们 -s add.o再看下:
add前面Bind的值变成了LOCAL,这时候对外就不可见了。这也就是在全局的时候,起的作用,将对应的变量static的作用,或者函数的可见范围,变成只对自身可见,对外不可见。
这个是为了降低重名的几率,也是防止自身的全局变量被外部访问,瞎修改的风险。
为了说明这个情况,我们来演示下这个过程,add.c改成这样:
hello.c 改成
编译执行后,最终结果输出17,是不是让我们一下子就不明白,a b两个值被外部随意修改,导致没法看懂代码业务。
我们看到有两个类型是 的数据,全局的,a和b。这样子这两个值就是可以被外部引用,进行修改的了。
如果我们把 add.c 中的 int a=5;改成 int a=5;那么最终链接的时候hello.o 就找不到a变量,导致链接失败。
这也就是的作用,让只想对当前的.c能访问,做的对修饰的变量或者函数进行限定。
于是,我们常规的模式就是,对内的都用进行修饰,然后放出对外函数,让其操作数据,保证入口的统一性,也更容易追踪。具体如下:
用静态修饰变量,不让外部直接访问,然后对外放出函数,让其通过函数修改数据,保证了入口的唯一性,这样子调试也很简单,直接在函数设置断点,打印堆栈,直接能找到调用方。
而如果说你让int a这种随意的变量放置到全局,就是一个灾难,会出现莫名奇妙被修改,找半天找不到被谁修改的问题。
说完了全局变量,全局函数前面加,下来说下函数内部,添加的妙用。
函数中的局部变量,默认是都在栈上面,这类变量最大的特点就是,函数返回之后,这段区域就会被其他函数调用时覆盖static的作用,重复利用,这也是栈的特点。
那么如果我们想做一个记数,用来记录这个 add 函数被调用的次数。该如何设计呢?
我们可以用一个全局静态变量来记录,比如 int =0;
然后在add方法里面进行记数,这样来操作。
这样子不舒服的一点就是,本该是在add内部的一个变量,被丢到全局区域,这样子就会有个问题,会被本文件的其他地方调用,但我们设计的这个变量,只想让add函数用。
于是,我们可以这样子处理:
int add()
{
int =0;
++;
a+b;
}
这样子操作后,就会从栈区域进到全局变量区域,但是又能保证只对add函数可见,其他函数都调用不到。
你说,妙哉否?
我们在学习一些语言,技巧的时候,尽量要去思考它的使用场景,这样子的话,你就知道,它的每个设计,都是为了解决一类问题,也就是需求推动设计。
好了,今天就说的这里,不知道你学的开心不开心?下一节我们来说下,关于 关键字的用法,这个比较简单,我们下一节见!
喜欢,帮忙转发~~
~~ end not end ~~
我来说两句