重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
链接属性与C语言中各个目标文件及函数的链接过程有关,用于认定不同文件的标识符(即程序中定义的各种名称,包括变量名、函数名)是否是同一个实体。更通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指定了这两处变量c是否是同一个c。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、微信小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了青田免费建站欢迎大家使用!
简单来说,链接属性的作用就是让你能在a文件中决定要不要访问b文件中的变量、函数。
链接属性有三种:
对于external属性的标识符,不同文件中出现的多个同名称标识符指向同一个实体。在C语言中,用extern关键字在声明中指定以引用其他文件中定义的相同标识符。
对于internal属性的标识符,仅在当前文件内该标识符指向同一个实体。在C语言中,用static关键字在声明中指定让标识符变为该文件私有(只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal)。
对于none属性的标识符,在每个声明位置都是一个新的实体。C语言中,没有对应的关键字。
标识符的默认的链接属性与其出现的位置有关。
程序的全局变量、所有函数默认的链接属性为external。
其余标识符的默认链接属性为none。
在以下例子中,b、c、f的链接属性就是external:
typedef char *a;
int b;
int c(int d)
{
int e;
int f(int g);
}
在a文件中想要使用b文件中定义的external属性标识符,可使用extern关键字在a文件中声明。
即使该标识符所在位置默认链接属性为external,也建议使用extern关键字显式说明,有利于增加程序可读性。
在a文件定义了一个全局标识符,但不想被其他文件访问,可以对该标识符加上static关键字。
在a、b文件中定义了同样的标识符,通过static关键字可以避免多重定义问题。
再次提醒:只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal
multiple definition of 'a';
。warning: ‘a’ initialized and declared ‘extern’
。undefined reference to 'a'
,原理同2。以下代码一定程度上阐释了部分区别:
static int i; // definition
// static storage
// internal linkage
void f(void)
{
extern int i; // declaration
// refers to the static i at file scope
// note that even though the specifier is extern
// its linkage is intern (this is legal in both C/C++)
{
int i; // definition
// automatic storage
// no linkage
}
}
实际上链接属性和作用域是两个概念。之所以产生以上问题,因为internal属性标识符出现的位置都是在文件作用域,而none往往在代码块作用域。此处想引起读者对内链接更深入的思考,见问题2。
同一个标识符在链接中只能存在一个,那么通过内部链接的方式可以隔绝同名外部链接,且限定了外部编译单元不能访问该文件全局标识符。
a.c:
#include
static int a=3;
int main(void)
{
extern int a;
printf("a=%d\n", a);
return 0;
}
b.c:
int a=1;
编译后结果为:
a=3
以上仅为不完善的个人猜想,抛开隔绝外部链接这一点不谈,就内部链接这一名称而言,笔者对为什么要在同一个文件内部使用链接的设计仍然存疑,但目前该话题的答案超出了笔者的理解,因此更深入的讨论暂时留白。
拓展:感兴趣的同学可以尝试学习链接相关知识,或许会找到更确定的答案。
《Pointers On C》
Difference between internal and no linkage