extern 声明(不带初始化)extern + 无初始化 = 声明;否则(无 extern 或带初始化)= 定义
extern int x = 5; 带初始化 → 是定义,extern 被"升级"成定义一句话:"extern 只借不造——声明是借,定义是造;借了没人造就链接报错,造了两次也报错。"
extern 是跨文件共享的"介绍信"——告诉编译器这个变量/函数在别的文件里已定义,这里只是引用,不分配存储。函数声明默认就是 extern。
file1.c: int counter = 0;(定义,分配内存)+ file2.c: extern int counter;(声明,不分配)→ file2.c 能正常读写 counterfile1.c: int add(int a,int b){...} + file2.c: extern int add(int,int); → 可调用。函数声明默认 extern,不写也等价undefined reference(未定义引用)multiple definition(重复定义)。解决:一个定义 + 一个 extern 声明,或都加 static 私有化| 定义 | 声明 | |
|---|---|---|
| 写法 | int x = 5;(无 extern / 带初始化) |
extern int x;(extern + 无初始化) |
| 分配内存 | ✅ 分配 | ❌ 不分配 |
| 能出现几次 | 整个工程只能 1 次 | 可以很多次 |
| 常见报错 | 重复定义(多个定义) | 未定义引用(只有声明没定义) |
file1.c: int num = 10; + file2.c: extern int num; num++; → 链接成功,num = 11common.h 写 int global;,a.c 和 b.c 都 include → 报"重复定义"错误。因为 #include 是文本展开,两个文件各有一份定义(外部链接)file2.c: extern int counter; 但 file1.c 定义的是 static int counter; → 链接失败。static = 内部链接,只登记在自己 .o 内部符号表、不进全局符号表,extern 去全局表找不到 → undefined reference。extern 突破不了 staticextern int x;(接口),定义 int x = 0; 只放唯一一个 .c(实现);多个文件 #include "x.h" 全都能用extern int x = 5; 带初始化是定义不是声明;函数声明默认 extern 可省| 相邻概念 | 和 extern 的关系 | 孤立理解会犯的错 |
|---|---|---|
| static | 双胞胎,正好相反:static = 内部链接(锁文件内),extern = 外部链接(跨文件共享) | 以为 extern 能突破 static——不能,链接器不看内部符号 |
| #include | extern 是"借"(声明,不分配),include 是"展开"(文本粘贴) | 以为 include 头文件 = 定义了变量 |
| 声明 vs 定义 | extern + 无初始化 = 声明;无 extern 或带初始化 = 定义(extern int x = 5; 是定义!) |
以为 extern 永远只是声明 |
| 头文件 | 头文件放 extern 声明 = 接口;.c 放定义 = 实现 | 头文件放定义 → 多文件 include 重复定义报错 |
2026-08-03
每主题一页,复习时只翻本目录。