C 什么';使用extern和#包括头文件有什么区别?

C 什么';使用extern和#包括头文件有什么区别?,c,C,我开始质疑“extern”关键字的有用性,该关键字用于访问其他模块(其他文件)中的变量/函数。当我们使用#include preprocessor来导入包含变量/函数原型或函数/变量定义的头文件时,我们不是也在做同样的事情吗?否。#include是一个预处理器命令,它说“将其他文件中的所有文本放在这里”。因此,包含文件中的所有函数和变量都在当前文件中定义。extern是必需的,因为它声明符号存在且属于特定类型,并且不为其分配存储 如果您这样做: int foo; 在多个源文件之间共享的头文件中

我开始质疑“extern”关键字的有用性,该关键字用于访问其他模块(其他文件)中的变量/函数。当我们使用#include preprocessor来导入包含变量/函数原型或函数/变量定义的头文件时,我们不是也在做同样的事情吗?

否。#include是一个预处理器命令,它说“将其他文件中的所有文本放在这里”。因此,包含文件中的所有函数和变量都在当前文件中定义。

extern
是必需的,因为它声明符号存在且属于特定类型,并且不为其分配存储

如果您这样做:

int foo;
在多个源文件之间共享的头文件中,会出现链接器错误,因为每个源都会创建自己的foo副本,链接器将无法解析符号

相反,如果您有:

extern int foo;
在头文件中,它将声明在每个源文件的其他位置定义的符号

一个(且只有一个)源文件将包含

int foo;

它创建了一个foo实例供链接器解析。

但是,只要包含包含其定义的头文件,就不能在不使用extern int foo声明的情况下访问int foo吗,#include只是将包含文件中的文本插入到源文件中-编译器并不真正了解包含文件,也不专门处理它们。所以,如果你有A.c,B.c和c.c,每一个都有“intfoo”,并且你把它们链接在一起,你如何解析foo?它存在于3个不同的地方。extern的意思是,符号存在于其他地方。您可以使用它,但其他人负责创建它。您会发现,对于只有一个foo_fun()实例的函数,带有调用foo_fun()的模块的程序,无论是否使用外部程序,都可以工作。因此,在这种情况下,你应该尽量弄清楚这一点。当你进入一个共享的全局变量时,你需要非常清楚,有些编译器知道了,有些没有。@Midnight Blue:我认为你把编码约定与C规范要求的行为混淆了。通常的做法是将
extern
声明放在代码模块的头文件中,然后
#包含
头以获取这些声明,而不是自己声明。是标题中的
外部
提供了对变量的访问,而不是
#include
本身在标题中。但是与
extern类型数组[]有一个细微的区别!前者是一个暂定定义,将被视为
类型数组[1]在翻译单元结束前没有包含大小的定义时。但是如果你把
extern
放在它前面,你只会说“大小在别处给出”,而这正是你最想要的。