【问题标题】:Confusion over 'extern' keyword in CC中的'extern'关键字混淆
【发布时间】:2020-04-14 08:32:20
【问题描述】:

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

extern int i;

int main () {

..

int i = 1;

..

}

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

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

【问题讨论】:

  • 我已经很久没有写过任何 C 语言了,但据我回忆,答案是你有两个变量叫做 'i' - 一个在主函数本地定义,另一个是应该在其他文件中定义。
  • 我知道 'i' 是在 'main' 外部声明的,但它的内存是在 'main' 内部分配的。不,不完全是。声明了 两个 不同的i 变量。一个是外部全局变量i(假设在别处声明),另一个是main 函数的本地变量。所以,是的,堆栈上有分配给本地i 的内存,但它与分配给外部i 的全局内存不同。当您在main 中引用i 时,它看到的是本地的,而不是全局的。
  • 同一个标识符可以在程序的不同点表示不同的实体。在 main 函数之外声明的变量 i 具有 文件范围外部链接 。在main 函数内部定义的变量i 具有块作用域无链接。这是两个不同的实体。
  • '我知道'i'是在'main'外部声明的,但它的内存是在'main'内部分配的:false。你有两个变量。 (i) 有两个is,所以答案是“两者”。 (ii) extern i 的作用域是全球性的;本地方法i 的范围是本地方法。

标签: c extern


【解决方案1】:

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 通常由普通编译器在堆栈上分配,如果实际需要的话。 (如果程序实际上并没有使用它,或者编译器可以通过优化消除对它的使用或将它们折叠到其他表达式中,它可能不需要为它实际分配任何堆栈空间。)i所引用的对象与块外i 引用的任何对象都没有关系。

【讨论】:

    猜你喜欢
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    相关资源
    最近更新 更多