了解 C 中的 `extern` 存储 class 说明符

Understanding `extern` storage class specifier in C

考虑给定的 C 代码:

#include<stdio.h>
extern int i;
int main(){
    printf("%d", i);
    return 0;
}

给出Compilation error。而如果我初始化 extern int i=10; 那么输出是 10.

#include<stdio.h>
extern int i=10; //initialization statement
int main(){
    printf("%d", i);
    return 0;
}

此外,如果我分配 int i=10;,则输出为 10

#include<stdio.h>
 extern int i;
 int i=10;  //assignment
int main(){
    printf("%d", i);
    return 0;
}

#include<stdio.h>
 extern int i;
 int main(){
    int i=10;   //assignment
    printf("%d", i);
    return 0;
}

变化:

#include<stdio.h>
 extern int i;
 int i=20;
 int main(){
    int i=10;
    printf("%d", i);
    return 0;
}

因为int i是局部变量,所以输出是10.

Please, can you explain some important point about extern storage class in C


我在某处读到,声明声明了变量或函数的名称和类型。定义会导致为要定义的变量或函数体分配存储空间。同一个变量或函数可以有多个声明,但该变量或函数只能有一个定义。

extern int i; 声明只是告诉编译器某处(在这个或另一个源中)存在全局范围内 i 的实际声明。它本身并不是 i 的实际声明。因此,在该声明中为 i 赋值是不合适的(这就是第二次尝试无效的原因)。您的第一次尝试无效,因为您没有 i.

的实际声明

你的第三个没问题,因为你有 i 的实际声明,但你不必有 extern int i; 声明。

您最后的样本在本地和全球范围内都涉及 i。在这种情况下,将使用局部范围内的变量。这就是为什么你没有打印 20。

extern storage class 说明符用于提供对所有程序文件可见的全局变量的引用。当你使用'extern'时,变量不能被初始化,但是它将变量名指向一个先前定义的存储位置。

考虑

int i;

在程序的所有函数之外声明,包括 main

这意味着 i 将有

  • 文件范围
  • 静态存储时长
  • space分配给i。 #这很重要。

考虑

extern int i;

在程序的所有函数之外声明,包括 main
这意味着 i 将有

  • 文件范围
  • 静态存储时长
  • i 仅声明,未定义,这意味着 space 未分配。
  • i 假定在其他地方定义,可能是在包含文件中

考虑

extern int i=10; 

在程序的所有函数之外声明,包括 main
这是您初始化 extern 变量 i 的情况。在这种情况下

  • Space 分配给 i.
  • i 将被初始化为 10
  • 关键字 extern 被忽略,这意味着 i 不是 declared only

备注

对于extern int i,必须在别处定义变量,即在另一个源文件中。如果不是这种情况,您将出现编译时错误。

当代码通过 extern 修饰符引用一个符号时,这意味着该符号实际上是在别处而不是在当前文件中定义的。

一个例外,如果extern修饰符用于当前文件中实际定义的符号,则可以。