tap*_*and 10 c extern storage-class-specifier output
我正在运行以下代码编译为: gcc A.c B.c -o combined
计划A:
#include<stdio.h>
int a=1;
int b;
int main()
{
extern int a,b;
fun();
printf("%d %d\n",a,b);
}
Run Code Online (Sandbox Code Playgroud)
方案B:
int a;
int b=2;
int fun()
{
printf("%d %d\n",a,b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在运行"组合"程序时,输出为:
1 2
1 2
Run Code Online (Sandbox Code Playgroud)
现在,我对这个问题有些疑惑:
为什么不输出:
0 2
1 0
是不是a和b定义了两次?
请清楚地解释一下,我在了解外部时遇到了很多问题,而且很少有这些疑虑不时出现.
提前致谢.
只要声明彼此一致并与定义一致,就可以多次声明变量.它可以在许多模块中声明,包括定义它的模块,甚至在同一模块中多次.
外部变量也可以在函数内声明.在这种情况下,必须使用extern关键字,否则编译器会将其视为局部变量的定义,该变量具有不同的范围,生命周期和初始值.此声明仅在函数内部可见,而不是在整个函数模块中可见.
现在让我再次重复一下extern的定义,其中"外部变量是在任何功能块之外定义的变量"(请仔细阅读BOLD中给出的单词).因此,对于Programe A a有定义,但b仅仅是声明,以便将的extern寻找它这是在给定的"B"的定义Programe B.所以从打印Programe A的1 2.现在让我们来谈谈Programe B它具有声明a和定义b因此被priting的价值a从programe A和值的b从当前文件.
所以,我在很长一段时间后回答我自己的问题。虽然声明:
int b;是声明,int b = 2;是定义
是正确的,但每个人给出的原因尚不清楚。
如果没有int b = 2;,int b;是定义,那么有什么区别呢?
区别在于链接器处理多个符号定义的方式。有一个弱符号和强符号的概念。
汇编器将此信息隐式编码在可重定位目标文件的符号表中。函数和初始化的全局变量获得强符号。未初始化的全局变量会得到弱符号。
所以在 中Program A,int a = 1是强符号int b;,而 是弱符号,同样在 中Program B,int b = 2是强符号,而int a是弱符号。
鉴于强符号和弱符号的概念,Unix 链接器使用以下规则来处理多重定义的符号:
所以,现在我们可以争论上述案例中发生的事情了。
int b = 2和int b,前者是强符号,后者是弱符号,所以b定义为值2。int a = 1和中int a,a 定义为1(同理)。因此,输出1 2.