使用标头文件中的全局变量我们可以在另一个文件中更改值/使用变量(相同的值可以在多个文件中访问/修改(,那么为什么可以使用外部?全球和外部有什么区别?
以下是我尝试过的示例,它没有在c。
中的外部变量和全局变量之间有所不同程序编译并成功运行而没有任何错误。
t.h
int i;
t1.c
#include<stdio.h>
#include "t.h"
int main()
{
i=10;
printf("%s i = %dn",__func__, i);
t2();
printf("%s i = %dn",__func__, i);
i=200;
printf("%s i = %dn",__func__, i);
t3();
printf("%s i = %dn",__func__, i);
return 0;
}
t2.c
#include<stdio.h>
#include "t.h"
void t2()
{
printf("%s i=%dn",__func__, i);
i = 100;
printf("%s i=%dn",__func__, i);
}
t3.c
#include<stdio.h>
#include "t.h"
void t3()
{
printf("%s i=%dn",__func__, i);
i = 300;
printf("%s i=%dn",__func__, i);
}
输出:-GCC T1.C T2.C T3.C
main i = 10
t2 i=10
t2 i=100
main i = 100
main i = 200
t3 i=200
t3 i=300
main i = 300
请参阅C11 6.9.2p2
对具有文件范围的对象的标识符声明没有初始化器,并且没有存储级规范符或存储级规格静态,构成了暂定定义。
这就是您所拥有的:暂定定义。
尝试文件T.H
中的不同变化int i;
int i = 42;
static int i;
static int i = 42;
extern int i;
GCC文档中各种选项的描述可能有帮助
-fno-common
在C代码中,此选项控制未经初始化器定义的全局变量的放置,在C标准中称为暂定定义。暂定定义与用外部关键字的变量声明不同,而这些变量不会分配存储。
UNIX C编译器传统上对公共块中非初始化的全局变量进行了分配的存储。这允许链接器解决不同汇编单元中同一变量的所有暂定定义,以与同一对象或非接待定义。这是-FCOMMON指定的行为,是大多数目标中海湾合作委员会的默认行为。另一方面,ISO C不需要此行为,并且在某些目标上可能会对可变参考的速度或代码大小惩罚。
-fno -common选项指定编译器应该在对象文件的BSS部分中放置非初始化的全局变量。这会抑制链接器暂定定义的合并,因此,如果在一个以上的汇编单元中定义了相同的变量,则会获得多个定义错误。使用-fno -common编译对其提供更好性能的目标很有用,或者如果您希望验证该程序是否会在其他情况下始终以这种方式对待非初始化的可变定义。