前言:
很多刚学 C++ 的同学,学到extern和全局变量的时候直接懵了:
extern int a;、extern int a=10;、int a;,长得差不多,为什么有的是声明、有的是定义?
很多教材会把它们叫做引用性声明、定义性声明,术语一多更容易混淆。
这篇我们从内存分配的角度,把规则、例子、坑点一次性讲清楚。
🎃
前置说明:
- 引用性声明 = 单纯声明:只告诉编译器有这个变量,不分配内存
- 定义性声明 = 变量定义:为变量开辟内存,分配内存 C++ 标准里,定义本身属于声明的一种;学习时我们习惯把「单纯声明」和「定义」分开理解。
✅ 核心判断口诀
extern后面不带= → 单纯声明;
只要有=初始化,或者全局直接写int a; → 定义。 判断本质:会不会分配内存。
一、三种写法逐条拆解
1. extern int num1; —— 引用性声明(单纯声明)
extern int num1;
特点:
类比:和函数声明 void print(int); 逻辑一样,只告诉编译器 “有这个东西”,没有实体。
2. extern int num1 = 10; —— 定义性声明(定义)
extern int num1 = 10;
⭐只要带上=初始化,前面的 extern 直接失效,它不再是声明,是定义!
特点:
3. int num1;(写在全局,函数外部)—— 定义性声明(定义)
int num1;
特点:
| extern int num1; | 引用性声明 | 单纯声明 | ❌ 不分配 | ✅ 可以多次 | 不能写=初始化 |
| extern int num1 = 10; | 定义性声明 | 定义 | ✅ 分配 | ❌ 仅 1 次 | 必须带初始化 |
| int num1;(全局) | 定义性声明 | 定义 | ✅ 分配 | ❌ 仅 1 次 | 写在全局,默认初始 0 |
二、同文件的省略规则
如果全局变量定义写在前,使用在后,并且在同一个.cpp文件里:extern 引用性声明可以省略。
示例 1:定义在前,无需声明
#include <iostream>
using namespace std;
int num1 = 10; // 全局定义
int main()
{
cout << num1; // 直接使用,不需要extern声明
return 0;
}
示例 2:定义在后,需要 extern 声明
#include <iostream>
using namespace std;
int main()
{
extern int num1; // 必须写引用性声明,编译器才能识别num1
cout << num1;
return 0;
}
int num1 = 10; // 全局定义写在main后面
![]()
三、跨文件完整演示代码(最常用场景)
文件 1:a.cpp(定义)
#include <iostream>
using namespace std;
// 下面三种定义写法,只能选一个,不能同时写
// int num1 = 10;
// extern int num1 = 10;
int num1; // 全局定义,默认初始值0
文件 2:b.cpp(使用这个全局变量,只写引用性声明)
#include <iostream>
using namespace std;
// 引用性声明:告诉编译器,num1在别的cpp里面定义好了
extern int num1;
int main()
{
cout << "一开始 num1 = " << num1 << endl;
num1 = 20;
cout << "修改后 num1 = " << num1 << endl;
return 0;
}


四、文末小结
希望可以帮助到大家,感谢观看,如果觉得文章对你有帮助的话,请点赞收藏关注支持一下博主😍,如有不足请指点,我及时改正!👻一起加油!嘻嘻😜

网硕互联帮助中心





评论前必须登录!
注册