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

时间:2014-02-14 08:41:57

标签: c++ c extern

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

在搜索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的行为吗? 我对此感到困惑。 如果这不是一个有效的问题,请原谅我。 先谢谢你。

6 个答案:

答案 0 :(得分:5)

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-),链接器不需要它,因此您的可执行文件可以成功构建。

答案 1 :(得分:3)

第一个版本失败,因为您还必须提供extern声明变量的定义,即通过链接其他一些具有

的C文件
int var;

在其全球范围内。

int var = 10; shadows全球声明中的main()行以来,第二个成功;如果您希望变量是extern,即在许多C文件之间共享,这通常是一件坏事。当然,这种共享本身通常也很糟糕(参见:global variables)。

答案 2 :(得分:1)

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

<强>的main.cpp

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

<强> var.cpp

int var;

然后你就不会遇到链接器错误,因为链接器会在main.cpp中使用var并使用var.cpp中的decleration

在您的第二个示例中,您已定义extern int var,但您从未参考过它。 int var = 10与外部int var完全不同extern int var。当链接器运行时,它会注意到您从未使用过{{1}}变量,因此无需搜索它。

答案 3 :(得分:1)

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

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

extern关键字。

使用extern关键字编译器声明any变量时,会尝试查找声明之前或之后可以出现的同一变量的定义。

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

您可以浏览this以更好地了解extern关键字。

答案 4 :(得分:1)

如果你已经声明了一个全局变量,那么在file1.cpp中说double myvar=5并且你想在file2.cpp中访问该变量,然后在你的file2.cpp中声明为

extern double myvar;

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

回到例子:

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

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

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

答案 5 :(得分:0)

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

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