听到「隐身术」三个字,我和小弦子眼里瞬间就开始放光,就连旁听的六叔叔注意力都集中了几分。
就在我们都静等老爹下文的时候,老爹却偏偏不着急讲了,又是喝水,又是擦眼镜什么的,一幅不慌不忙的样子,恨得我牙根儿都痒痒。
吊足了我们的胃口后,老爹这才回到自己的电脑旁边徐徐说道:「一直以来,因为我们的程序功能比较简单,所以程序里面就只有一个.c文件,但是随着我们的程序越来越复杂,如果还把所有代码都放在一个.c文件中就显得特别臃肿,不方便阅读。
其实推箱子这个程序已经暴露出来这个问题了,有时候我们需要查看某行代码的时候,往往要翻阅很久。
于是乎我们就要对程序的功能进行分块,各个块完成相应的一些小功能。最后把小功能组合在一起,就完成了一个大的功能了。
为了方便管理和阅读,一般我们就会按块来创建.c文件,也就是说,程序中可能会存在多个.c文件。
在默认情况下,我们定义在一个.c文件的全局变量毫无秘密可言,因为其他的.c文件可以通过一个关键字——external让它显出真身,然后就可以肆无忌惮地把它的脸按在地板上摩擦。
比如说我们在zhangsan.c文件里声明了一个全局变量:
int heart = 10;
然后还有一个lisi.c文件,它想看看zhangsan.c中的heart是什么,于是它就在自己声明全局变量的地方写了这么一句:
external int heart;
这个时候在lisi.c中就能对zhangsan.c中的heart为所欲为了。
那这样会不会有什么问题么?」
老爹抛出了他的疑问。我和小弦子对视了一眼,相互摇了摇头。
问题肯定是有的嘛,不然老爹怎么可能会无的放矢,跟我们扯这么多有的没的。
「既然你们想不到,那我就给你们设置个场景。
假设我们把一个.c文件比作是一个人,那么.c文件中的变量就是我们身体的器官。像手啊,脚啊,这种类型的器官暴露在外面倒是没什么,甚至让人摸两下也没什么大问题。
可是像我们的心脏这类器官能够暴露在外面么?哪天随便来个人跟我们说,让我们把心脏给Ta看看,摸两下,你说这让不让人害怕?
所以基于安全等各方面的因素,心脏这类的器官必须藏起来,不能虽然让人触碰。
人生在世,谁还没有点小秘密了?.c文件也是一样的啊,总得有点自己隐私吧?
所以说啊,如果我们让一个全局变量只能在当前.c文件,也就是声明这个变量的.c文件中能够使用,就用static关键字修饰它。一旦一个全局变量被static关键字修饰,那么其它的.c文件就不能在使用external关键字获取了。
换句话说,被static修饰的全局变量就在其它.c文件面前消失了,这个就是static的隐身功能。
有一点要注意啊,刚刚说的内容都是针对的全局变量,如果是局部变量根本就不存在这个问题。」
我和小弦子若有所得,就连旁听的六叔叔居然都露出一副「原来如此」的表情。
「static除了能够修饰全局变量,还可以修饰函数哦。同样的道理,如果一个函数被static修饰了,那么这个函数也就只能在定义它的.c文件中使用了。
对于函数而言,如果要在其它的.c文件中调用它就不能靠external关键字了,而是要靠头文件,也就是.h文件。
还记得我们每一个程序都要写的#include<stdio.h>么?stdio.h就是一个头文件。
好了,光说不练假把式,那接下来我就用代码给你们演示一遍。
假设我们有一个专门对圆进行计算的功能模块,于是定义一个circle.c,内容如下:
double PI = 3.1415926;
double circleMianJi(double r)
{
return PI * r * r;
}
double circleZhouChang(double r)
{
return 2 * PI * r;
}
如果要让circleMianJi和circleZhouChang这两个方法能够在其他.c文件中调用,这个时候我们就要再创建一个xxx.h文件,并且将这两个函数的声明部分放在那个xxx.h文件中。
这个时候xxx.h和circle.c还没有任何关系,所以我们需要在circle.h中包含xxx.h,这样它们才会建立起联系。
有一点要注意,包含一个我们自己定义的.h文件就不能再用<>了,而要用双引号,为了方便表示,我们就新建一个circle.h:
#include
double circleMianJi(double r);
double circleZhouChang(double r);
然后circle.c的内容也要作出相应变化:
#include “circle.h“
double PI = 3.1415926;
double circleMianJi(double r)
{
return PI * r * r;
}