前言
对于C语言的链接属性,比较模糊,因此今天回归一下课本上的知识,并记录一下,方便自己回顾。
正文
链接属性
链接属性用于认定不同文件的标识符(比如变量名、函数名)是否是同一个实体。
通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指定了这两处变量c是否是同一个c。
链接属性一共有三种:external(外部链接),internal(内部链接)和 none(无链接)。
external链接属性的变量可被所有源文件所访问,只需要申明一下(比如 extern int a)
internal链接属性的变量只能在其定义的源文件内访问
none链接属性的变量只在其作用域开始到结束内可被访问(可以看成函数内定义的变量)
external
对于external属性的标识符,不同文件中出现的多个同名称标识符指向同一个实体。
在C语言中,用extern关键字在声明中指定以引用其他文件中定义的相同标识符。
internal
对于internal属性的标识符,仅在当前文件内该标识符指向同一个实体。
在C语言中,用static关键字在声明中指定让标识符变为该文件私有。
只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal
none
对于none属性的标识符,在每个声明位置都是一个新的实体。
C语言中,没有对应的关键字。
默认的链接属性
标识符的默认的链接属性与其出现的位置有关。
程序的全局变量、所有函数默认的链接属性为external;
static修饰的变量拥有internal链接属性;
其余标识符的默认链接属性为none;
- int a;
- void fun_b(){
- }
上面代码中,变量a和函数fun_b默认链接属性是external。
- void fun_b(){
- //局部变量,只在函数fun_b中有效
- int c;
- }
上面代码中,变量c默认链接属性为none。
static
static可以链接链接属性,但是,这只对缺省链接属性为external的生命才有改变链接属性的效果。
- static int a;
- static void fun_b(){
- //默认链接属性为none,static修改无效
- static int c;
- }
上面变量a和函数fun_b的链接属性被改变为internal。
但static修饰局部变量c,那可能达不到效果!
再次提醒:只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal
extern
extern关键字的规则更为复杂。一般而言,它的标识符(变量)指定为external链接属性,就可以表示所有源文件都可以访问这个实体。
- int func(){
- //b是在别的源文件申明了
- //加上extern,也就是可以访问其他源文件的b
- extern int b;
- }
即使该标识符默认链接属性为external,也建议使用extern关键字显式说明,有利于增加程序可读性。
当一个extern关键字用于源文件中标识符(变量)的第一次声明,那该标识符具有external链接属性。但是,如果extern用于第二次或以后得声明时,并不会改变第一次声明所指定的链接属性。
- static int i;//internal链接属性
- int func(){
- extern int i; //此时用extern修饰,也不会改变链接属性,依旧是internal
- }
例子
PS :VS环境下
- 1. a.h [空文件]
- 2. a.c
- 3. hello.c
a.c
- # 默认是external链接属性
- #等同于 extern int b = 125
- int b = 125;
- static int c = 999;
hello.c
- #include<stdio.h>
- //引入定义的头文件
- #include "a.h"
-
- int main(void){
- extern int b;
- //会提示找不到int c,因此int c在a.cpp中有static修饰
- extern int c;
- printf("b=%d\n", b);
- printf("c=%d\n", c);
-
- getchar();
- return 0;
- }
因为c是在a.cpp中定义为static,也就是internal链接属性,在hello.cpp中使用extern时是无法改变第一次声明的链接属性,因此上面编译是报错。
参考文章
《》
《》
《》
《》