对不起这类问题。但是,我对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
的行为吗?
我对此感到困惑。
如果这不是一个有效的问题,请原谅我。
先谢谢你。
答案 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
声明变量的定义,即通过链接其他一些具有
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函数的范围内声明了一个新的阴影全局声明。