为什么在C中的标题中使用extern关键字?
为什么要在以下代码中使用为什么在C中的标题中使用extern关键字?,c,extern,linkage,C,Extern,Linkage,为什么要在以下代码中使用extern关键字: 标题.h float kFloat; // some say I should write 'extern float kFloat;', but why? 文件.c #include <stdio.h> #include "Header.h" float kFloat = 11.0f; #包括 #包括“Header.h” 浮动kFloat=11.0f; main.c #include <stdio.h> #inclu
extern
关键字:
标题.h
float kFloat; // some say I should write 'extern float kFloat;', but why?
文件.c
#include <stdio.h>
#include "Header.h"
float kFloat = 11.0f;
#包括
#包括“Header.h”
浮动kFloat=11.0f;
main.c
#include <stdio.h>
#include "Header.h"
int main(int argc, const char * argv[])
{
printf("The global var is %.1f\n", kFloat);
return 0;
}
#包括
#包括“Header.h”
int main(int argc,const char*argv[]
{
printf(“全局变量为%.1f\n”,kFloat);
返回0;
}
这个代码有效。全局变量kFloat默认为外部链接和静态生存期
输出为:
全球风险值为11.0
我不明白在哪种情况下会出现问题,有人能给我一个它会崩溃的例子吗?
extern
表示您要使用的项目(或功能块外部)中的某个地方定义了一个变量。它不会为它分配内存,因为您告诉编译器这是在其他地方定义的
变量必须在程序的一个模块中定义一次。如果没有定义或定义不止一个,则可能在链接阶段产生错误
定义是指创建或分配变量存储的位置;声明是指声明变量性质但未分配存储的位置
由于它在其他地方可以访问,所以它需要是静态的
extern float kFloat;
声明kFloat
,但不定义它
但是:
还声明了kFloat
,但这是kFloat
的暂定定义
添加extern
只会抑制暂定定义。在头文件中,您只需要声明,而不需要定义
如果试探性定义包含在多个源文件中,那么您最终将拥有同一对象的多个定义,而该对象在C中是未定义的行为。始终将全局变量(如
float kFloat;
)的定义放在.C文件中,并将声明(如extern float kFloat;
)在标题中
否则,当多个.c文件包含相同的头时,将出现多定义错误。首先,奇怪的是您的代码正在编译。对于
文件.c
中的kFloat
变量的双定义,它应该抛出编译时错误
其次,如果您试图在两个文件中使用公共变量,则不应在头文件.h
中定义它。您应在头文件中使用extern
关键字,以便包含头文件.h
的文件知道它已在外部定义
现在,您可以在任何c文件中全局定义变量,然后将该变量用作公共变量。为什么要使用extern…? 不应该。简单明了。因为不应该使用全局变量,而且它们是唯一需要
extern
关键字的变量
每当您想使用全局变量时,请三思。在绝对最大值时,您可能需要使用具有文件作用域的变量(使用
static
关键字),通常这样一个变量会伴随着一些操作/使用其值的函数,但变量本身不应该在文件范围之外可见。使用全局变量只会导致难以处理的混乱代码,几乎不可能在不引入大量错误的情况下进行更改。但是hea中的定义der有默认的外部链接,因此我不需要extern关键字来访问变量。我使用c11编译器,甚至在c99上尝试过它,但都没有警告。@ViktorLexington:头文件中的定义是暂定的,因为它没有在那里初始化。因此它不会抛出任何错误,因为它没有冲突任何真正的定义。当kFloat在file.c中初始化时,它得到了真正的定义。因此相同的变量在main.c和file.c中以相同的值可见。现在,特别是在这种情况下,在您初始化头文件中的变量之前,不需要使用extern。但是我建议在头文件中使用extern,因为如果没有de,您将得到错误任何一个c文件都提供了定义。有关详细信息,请参阅以下帖子中的答案:我无法重现定义错误,我不太理解您的意思。@ViktorLexington链接时出错,而不是编译,是您进行链接的吗?我运行main.c代码,输出打印时没有问题,因此它们都是链接的。并且输出值是11.0。@ViktorLexington我明白了。所以在main.c中,您仍然有float kFloat=11.0f;
这是一个暂定的定义,请参阅@ouah的答案,他对此有更好的解释。要重现多定义错误,您需要删除它,并且在标题中只有定义。@ViktorLexington,如果我理解的话。@ViktorLexington正确地说,暂定定义仍然是定义,因此如果标题包含在多个文件中,您将有未定义的行为。未定义的行为意味着即使在一台机器上一切正常,在另一台机器上也可能没有。但我的变量已定义。两者都是外部链接和静态生存期。那么您的观点是什么?一些书籍建议使用全局常量变量而不是宏,因为添加了类型信息。啊,是的,这将是extern
关键字的一种有效用法,因为这样的“变量”不是变量而是常量。然而,其他书籍不鼓励使用const
变量,因为C无法消除此类变量的运行时存储如果C++不使用<代码> >定义> /COD>,我将使用<代码> EnUM <代码>或<代码>静态const <代码>变量,用于编译时常量,而不是<代码> ExtNe>代码>。在断言后面有一个真实的元素,但也有一个过语句的元素。例如,全局变量<代码> STDIN < /C>code>stdout和stderr
比任何
float kFloat;