目录

对 C 语言中 extern 的理解


extern 告诉编译器,变量 i 是在程序中的其他位置定义的(很可能是在不同的源文件中),因此不需要为 i 分配空间

一个全局变量可以声明多次,但只能定义一次。只要在任意一个文件中只定义一次就可以了,其他文件中如果要使用需要先用 extern 声明。如果其他文件中没有使用 extern 声明,则会报重复定义的错误

注意extern int a是声明而extern int a = 0是定义,要分清楚

在多文件的工程中,有如下几种用法(假设 A 包含源文件和头文件,B 和 C 包含源文件,B 和 C 要使用 A 中定义的变量 a):

A 的源文件中定义,B 和 C 的源文件中使用前先 extern,此时可以没有头文件

1
2
3
4
5
6
// A.c
int a = 0;     /* 可以赋值也可以不赋值 */

// B.c & C.c
extern int a;  /* 不可以直接 extern int a = 1,这相当于重复定义 */
a = 1;

A 的源文件中定义,头文件中声明,B 和 C 通过包含 A 的头文件使用

1
2
3
4
5
6
7
8
// A.c
int a = 0;     /* 可以赋值也可以不赋值 */
// A.h
extern int a;  /* 不推荐直接在头文件中进行定义 extern int a = 0,别的文件包含后会重复定义 */

// B.c & C.c
#include "A.h"
a = 1;

A 的源文件中未定义只声明,在 B 和 C 任意中定义

1
2
3
4
5
6
7
8
// A.c
extern int a;        /* A 中声明 */

// B.c
int a = 0;           /* B 中定义 */

// C.c
extern int a = 0;    /* C 中声明 */

总之,C 语言的全局变量是所有文件均可见的,extern 只是告诉了编译器这个变量不是在该文件中定义的。在整个工程中,一个全局变量只能被定义一次,被声明和使用无数次。在非全局作用域下,可以定义同名的变量,这就涉及到作用域的问题