c语言中的连接属性,extern与static
在《c和指针》第三章提到连接属性有三种,external,internal,none
在函数内定义的变量都是none连接属性,这个用到的很少,不具体介绍。
external与internal连接属性都是用来描述全局变量以及全局函数的。下面详细介绍这两种连接属性:
(1)external连接属性,也叫外部连接属性。
我们一般定义的全局变量,如果前面没有加入static关键字,那么这个全局变量的连接属性就是external的,请注意在定义全局变量时请在源文件中定义,也就是在.c文件总定义,声明时在头文件中进行声明。
虽然我们可以在头文件(.h文件)中定义全局变量,但是这样会引入一些不好的bug。具体会引入什么错误,我们下面会详细讲。
external连接属性的全局变量以及函数的含义就是,在一个文件中定义的external连接属性的全局变量以及函数在另一个文件中也可以访问。
例子1
1 //a.c 2 3 int a=10;//定义全局变量a,其连接属性是external 4 5 void print(){ 6 7 }
1 //main.c 2 3 #include<stdio.h> 4 extern int a;//因为要调用a.c定义的变量,因此在此处进行声明 5 extern void print();//因为要调用在a.c定义的函数,在此处声明 6 7 int main(){ 8 9 printf("a=%d\n",a); //打印在a.c定义的变量的值 10 print(); //调用在a.c定义的函数 11 return 0; 12 13 }
上述代码是可以正确运行的。
如果全局变量的定义放在头文件中,也就是.h文件中,如果要在另外一个文件中对定义在头文件中的external连接属性的变量进行访问,
不能通过extern关键字仅仅在源文件中进行声明,需要把头文件用include命令包含进源文件。
例子2
1 //a.h 2 3 int a=20;//在头文件a.h中定义一个全局external连接属性的变量 4 5 void print(){ 6 7 }
//main.c源文件 #include<stdio.h> //仅仅在源文件中进行了声明,并未把a.h这个头文件包含进来 extern int a; extern void print(); int main(){ printf("a=%d\n",a); print(); return 0; }
上述代码在连接时会出现错误,错误如图

当我们把a.h头文件包含进main.c源文件时,便可以顺利执行了。
正如上面所说的,extern int a;这是一个声明,如果整个工程的别的地方没有int a;语句,extern int a;这条语句就是变量的定义。在例子1中,在头文件a.c中
int a=10;就是对变量a进行定义,在main.c中的extern int a;是对变量a进行声明,如果在a.c中没有int a=10;,那么在main.c中的extern int a;便变成了变量a的定义。
请注意:如果在a.c中定义了int a=10;,在main.c中的声明是extern int a=12;那么再编译时就会出现错我,因为extern int a=12此时不再是变量的声明,
而是变量的定义,那么这时在连接时就会出现重复定义的语法错误。

(2)internal连接属性,也叫内部连接
在全局变量以及函数中定义中加上static,那么变量和函数就变成了内部变量与内部函数,意思就是这种内部连接属性的变量和函数只能在当前文件中被访问,
不能被别的文件里面的函数访问。
在内部连接属性中需要注意的一点就是,如果某一个全局变量或者函数只需要在当前的文件中进行访问,不需要再别的源文件中进行访问。那么这种函数与全局变量一定不能在头文件中进行定义,如果一个内部变量在头文件a.h中进行了定义,那么任何一个包含a.h头文件的源文件都可以访问这个变量,那么内部变量的意义就不存在了

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号