📄 一句话概括
存储类别回答两个问题——变量"住哪儿"(内存的哪块地方)和"活多久"(生存期)。四个类别:auto(默认,住栈上、随函数生灭)、static(住静态区、活到程序结束)、register(建议放寄存器,现代基本被忽略)、extern(声明"这个变量在别处有")。
📝 本节和前面几节的关系
6.4 讲的是"谁能看见"(作用域),这一节讲"住哪、活多久"(生存期)——两个维度是分开的,这是全节最重要的观念。初学时很多困惑("函数里的变量怎么一出函数就没了""怎么让变量记住上次的值")都要靠这一对概念才能解开。
一、两个维度,千万别混
| 维度 | 管什么 | 相关小节 |
|---|---|---|
| 作用域 | 名字在哪些代码里看得见 | 6.4(全局 / 局部 / 块内) |
| 存储类别 | 变量住在内存哪一块、从生到死多久 | 本节(auto / static / register / extern) |
一个变量同时具备这两个属性。看个例子:函数里的 static 变量——作用域是局部的(外面看不见这个名字),生存期是全局的(命一直活到程序结束)。这正是下一节最反直觉、也最有用的知识点。
二、四个类别速览
| 类别 | 住哪 | 活多久 | 什么时候用 |
|---|---|---|---|
| auto | 栈(stack) | 函数进来时生、返回时死 | 默认就是它——平时写变量都在用它 |
| static | 静态存储区 | 程序开始到结束 | 想让变量"记住上次的值" |
| register | 建议放 CPU 寄存器 | 同 auto | 现代基本不用(编译器自己会优化) |
| extern | 别处定义的那块地方 | 同被声明的那个变量 | 跨文件共享全局变量 |
三、一个直观的比喻(把内存想成一栋楼)
| 楼层 | 对应变量 | 特点 |
|---|---|---|
| 栈 | auto | 临时客房——函数一进来开房,一走就退房 |
| 静态区 | static / 全局 | 长期住户——从开门住到关门 |
| 寄存器 | register | 贴身口袋——存取最快,但位置极少 |
| 堆 | (第 7 章) | 自租仓库——自己申请、自己归还 |
顺带记住:栈是"自动打扫"的,堆是"自己负责"的。后者的麻烦,第 7 章才正式遇到。
四、动手 Demo:一屏看懂"生存期"
#include <iostream>
using namespace std;
int g = 100; // 全局变量(住在静态存储区)
void counter() {
int a = 0; // auto:每次调用都重新出生
static int s = 0; // static:只出生一次,之后一直活着
a++;
s++;
cout << "auto a = " << a << " , static s = " << s << endl;
}
int main() {
counter();
counter();
counter();
cout << "全局 g = " << g << endl;
return 0;
}
看到什么算成功:
auto a = 1 , static s = 1
auto a = 1 , static s = 2
auto a = 1 , static s = 3
全局 g = 100
这一屏就把"生存期"讲透了:a 每次都是 1(每次调用都是新生),s 却在长大(它没死过)。
30 秒实验:把 static int s = 0; 里的 static 删掉,重新运行——三行都变成 a = 1(s 也跟着变成 1 了,虽然名字还写着 static,名不副实,顺手把名字也改掉)。然后再加回来。删掉、加回——就是"活不过函数"和"活得比函数长"的区别。
五、常见误区
- "作用域和生存期是一回事"——最容易混的一点。函数里的 static 变量是标准反例:名字只在函数里看得见,命却活到程序结束。
- "局部变量没初始化一定是乱的"——对普通局部变量成立(2.3.2 的垃圾值),但
static变量和全局变量会被自动清零——这是能白捡的便宜。 - "写了 register 就跑得快"——现代编译器对寄存器的安排比人精准,写了它多半直接忽略。
- "extern 是定义一个变量"——它是声明("别处有这个东西",回看 6.1.2 声明 vs 定义),本身不分配空间。
自测三问(点开对答案)
1. 存储类别回答哪两个问题?——变量住哪儿(内存位置)和活多久(生存期)。 2. 作用域和生存期是一回事吗?——不是。函数里的 static 变量作用域局部、生存期全局。 3. auto 变量住在哪、活多久?——住在栈上,随函数进入而生、返回而死。- ☐ 6.7.1 auto变量(下一节)
相关笔记
- 变量作用域 —— 与"生存期"互为两个维度
- 变量的声明及赋值 —— 未初始化=垃圾值
- 函数的声明 —— 声明与定义的区别
- 🔷 C++基础 · 索引 —— 全课路线图