2017-05-28 64 views
1

我有2 C文件在下面。从我读的内容来看,我知道全局变量的默认存储类是extern。如果我明确键入它,我得到未定义的变量错误。我在这里错过了什么?这是否意味着当我省略extern关键字时,它就变成了一个定义,但是当我将它只输入一个声明时?C - 为全局变量明确写入extern关键字

file1.c中

#include <stdio.h> 
#include <stdlib.h> 
extern void file2function(); 

int variable; // if i put extern i will get error, isnt it implicitly extern? 

int main() 
{ 
    variable = 1; 
    printf("file1 %d\n",variable); 
    file2function(); 
    return 0; 
} 

file2.c中

#include <stdio.h> 
#include <stdlib.h> 

extern int variable; 


void file2function(){ 
    variable = 2; 
    printf("file2 %d\n",variable); 
    return; 
} 
+0

是的,除非你还提供初始化('extern int variable = 0;')。请参阅http://port70.net/~nsz/c/c11/n1570.html#6.9.2p4。请注意,C++对待它们的方式不同。 – PSkocik

+0

想一想如果你把所有的声明都放在extern中,那么应该在哪里分配存储空间?你无法区分唯一真正的定义。 – Jack

+0

所以我必须省略extern或者使用初始化工具来指出应该在哪里分配存储空间? – Splash

回答

4

You need to take a look at the difference between a definition and a declaration

这就是说,与extern存储变量声明是一个提示给编译器的对象是在其他地方定义了(或翻译单T)。这不是它自己的定义。

您需要在用于生成二进制文件的其中一个翻译单元中进行定义。

在你的情况下,如果你把extern都放在这两个文件中,int variable就成为两种情况下的声明。这就是为什么在连接阶段,编译器找不到定义这是承诺,所以它尖叫。

在另一方面,如果去掉extern从一个文件(只有一个),在该文件中,int variable;定义和其他翻译单元这个定义,所以,都好。

+0

谢谢你的解释。正如你所说的,我们必须给编译器一个提示。但是对于auto关键字“auto int a”陈述是一个定义,但“extern int a;”这只是一个减速?因为“void function(){auto int a; printf(”%d“,a); return;}”不会给我任何错误。我希望我明白了吗? – Splash

+0

@Splash:不要在C代码中使用'auto'。阅读存储类和定义与声明(使用链接Sourav给你)。 –

+0

@Splash yes,'extern'和'auto'是两种不同的存储类别说明符。 –