Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在C中的标题中使用extern关键字?_C_Extern_Linkage - Fatal编程技术网

为什么在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;