在c / c ++中使用extern背后的概念是什么?

对不起,这类问题。 但是,我对C\C++的关键字extern非常好奇。

在搜索extern解释时,我知道extern告诉编译器变量或函数已经在其他文件或程序中定义。

但如果这是一个案例那么我们为什么要使用extern

因为我尝试了一些代码如下:

 extern int var; int main(void) { var = 10; return 0; } 

这段代码给我一个错误信息,作为unresolved external symbol "int var" (?var@@3HA)

如果我使用的代码如下:

 extern int var; int main(void) { int var = 10; return 0; } 

它没有显示任何错误,并且给出了与我在main函数中定义的值相同的值。

那么,任何人都可以帮助我关于extern的行为吗? 我对此感到困惑。 如果这不是一个有效的问题,请原谅我。 先感谢您。

extern用于表示另一个翻译单元中的变量(“源文件”)。 例如,main.c中的代码如下所示:

 extern int var; int main(void) { var = 10; return 0; } 

此代码包含一个名为var的整数的声明,但没有定义,因为extern明确地说:“这个定义是在其他地方”

你可以定义另一个源文件,比如,other.c:

 int var = 0; 

然后,在将此新转换单元添加到构建命令后,程序将正常链接,并且两个文件中的代码都可以对共享var变量进行操作。

在第二个版本中,您只需在main函数中使用局部变量覆盖extern var的声明。 由于extern var不再使用(ODR-),链接器不需要它,因此您的可执行文件可以成功构建。

第一个版本失败,因为您还必须提供extern -declared变量的定义,即通过链接到其他一些C文件

 int var; 

在其全球范围内。

第二个成功,因为int var = 10; main()的行会影响全局声明; 如果你想要变量是extern,即在许多C文件之间共享,这通常是一件坏事。 当然,这种共享本身通常也很糟糕(参见: 全局变量 )。

extern用于指示变量存在于另一个编译单元中。 如果你有:

main.cpp中

 extern int var; int main(void) { var = 10; return 0; } 

和:

var.cpp

 int var; 

然后你就不会有链接器错误,因为链接器会在main.cpp中使用var来解决它在var.cpp中的变化问题

在您的第二个示例中,您已定义了一个extern int var但您从未引用它。 int var = 10是与extern完全不同的int var 。 当它们链接器运行时,它注意到你从不使用extern int var变量,所以不用费心去搜索它。

我建议你必须清楚你对变量的定义和声明的理解。

当你想说变量被分配了你想要只声明变量的内存时,会使用extern关键字。

当您使用extern关键字编译器声明任何变量时,将尝试查找在声明之前或之后可以存在的同一变量的定义。

在第一种情况下,您只是声明变量没有为其分配任何内存,即不定义变量。

你可以通过这个来更好地理解extern关键字。

如果你声明了一个全局变量,让我们说double myvar=5double myvar=5 ,你想在file2.cpp中访问该变量,然后在你的file2.cpp中声明为

 extern double myvar; 

在C ++中,每个文件都称为编译单元。 要将文件编译为目标文件,您需要声明所有变量,但不需要初始化或对这些变量进行赋值。

回到例子:

File1.cpp: double myvar=5这既是声明又是初始化。 您可以将file1.cpp编译为file1.o。

File2.cpp:假设您在myvar某个地方使用myvar ,并且您还希望在file1.cpp中访问该值(可能在计算之后)。 因此,为了能够将file2.cpp编译成file2.o,必须声明extern double myvar ,以便可以编译file2.cpp。 这将使编译器满意并将任务留给链接器。

现在您已经编译了这些文件,您将拥有名为(如果您使用的是g ++)file1.o和file2.o的目标文件(翻译单元)。 现在链接器将它们链接在一起并让file2.o访问myvar

声明变量extern告诉编译器变量的实际实例位于其他位置。 如果您不在其他地方提供它,链接阶段将失败。

在您的第二个示例中,您根本没有引用extern声明的变量。 您在main函数的范围内声明了一个新的阴影全局声明。