对 C 中的 'extern' 关键字感到困惑

Confusion over 'extern' keyword in C

我知道在 C 中,变量定义和声明的完成方式类似,除非我们使用关键字 extern,例如在以下代码中:

extern int i;

int main () {

..

int i = 1;

..

}

我知道 'i' 是在 'main' 外声明的,但它的内存是在 'main' 内分配的。我有两个问题: (i) i 是栈变量还是数据段上的变量(全局变量)? (ii) 我的范围是什么?如果两个文件的可执行文件在运行时链接在一起,是否可以在上述 .c 文件之外看到,或者我们是否需要 extern int i;每个文件中的声明?

请帮忙?我不熟悉 C/C++ 以外的语言;因此我很难理解变量定义和变量声明之间的区别。

extern int i; 声明,但不定义 i。如果使用此 i 并且某处没有定义它,链接通常会失败。如果它没有 extern,那么它只是说 int i;int i = 0;,它会定义 i。 (前者为暂定定义,无非暂定定义时默认为。)

由于 int i; 在一个块内(由 {} 包围的一系列语句,在本例中是定义 main 的块),它定义一个新对象。名称 i 指的是 main 之外和此块内部的不同事物(但在定义 int i; 之后)。

extern int i;声明的i的作用域是从声明到结束的整个文件。 (该范围包括 main 中的块,但此 i 被块内的 int i; 隐藏。从技术上讲,第一个 i 的范围包括该区域——它存在但隐藏且不可访问。)使用 extern 声明名称不会将其范围扩展到当前文件之外。相反,它给了它们链接,这意味着它们可以引用在另一个文件中以相同名称声明的相同对象。

int i; 声明的 i 的范围是从它的声明到它在其中声明的块的末尾。

main里面定义的i,一般编译器一般会在栈上分配,如果确实需要的话。 (如果程序实际上并不使用它,或者编译器可以通过优化消除对它的使用或将它们折叠到其他表达式中,则可能不需要实际为它分配任何堆栈 space。)此 i 与块外 i 引用的任何对象都没有关系。