今天在复习C的时候,看到关于#include语句的一个解释,如果B 中 #include A,就是将文件A拷贝到#include A的位置中。
根据这个原理,于是做了一个实验。在头文件中定义一个变量(非静态变量),同时声明一个fun函数。再写一个fun.c文件,fun.c文件中实现了fun函数,最后写一个main.c文件调用fun函数。
三个文件的源代码如下:
test.h#include#include void fun();int com;
fun.c#include "test.h"void fun(){ com = 0;}
main.c#include "test.h"int main(){ com = 4; fun(); printf("%d\n", com); return 0;}
, 很明显在链接的时候必然会出现“multiple definition of `com'”。一般而言也不会在头文件中定义变量和函数。只可以声明变量,比如使用static可以在头文件中声明变量。如下所示:
test.h#include#include void fun();static int com;
其他两个文件不做改动,编译、链接和运行都没有报错,输出结果是4. 因为静态变量存储静态存储区,但是静态变量的作用域是一个文件,fun.c, main.c都会为com定义一个本地变量,因此,fun对com的改动不会影响main中的com. 如果希望在fun.c中的改动对main有效果,可以使用extern.
test.htest.h#include#include void fun();extern int com;
main.c#include "test.h"int com;int main(){ com = 4; fun(); printf("%d\n", com); return 0;}
fun.c 无须改动,此时,程序的输出结果是0。
总结以下:extern变量可以声明一个外部变量,使得编译顺利用过,但是在链接之后才得到实际的变量。每一个文件中定义的静态变量都会在静态存储区中分别分配一个空间,静态全局变量的作用域是该文件。在头文件中一般不会直接定义变量和函数,仅仅作声明。