C++ 作用域与内存分区专题详解
作用域回答的是"这个名字在代码的哪个范围内可见";内存分区回答的是"这个变量的数据实际存在物理内存的哪个区域"。两者经常被放在一起讲,是因为变量的存储期(storage duration)决定了它住在哪个内存分区,而作用域规则又决定了谁能访问到它——理解了这层关系,后面很多"为什么"就不再需要死记硬背。
目录
第一部分:作用域(Scope)
- 作用域基础概念
- 块作用域(局部作用域)
- 全局作用域
- 命名空间作用域
- 类作用域
- 作用域嵌套与名字遮蔽
- 作用域 vs 生命周期 vs 链接属性
第二部分:内存分区
8. 程序内存布局总览
9. 栈区(Stack)
10. 堆区(Heap)
11. 全局/静态存储区
12. 常量存储区
13. 代码段
14. 变量归属速查表
15. 常见坑
第三部分
16. 高频面试题
第一部分:作用域(Scope)
一、作用域基础概念
作用域指的是一个标识符(变量名、函数名、类名等)在源代码中可以被合法访问的范围。这是一个纯编译期概念——编译器在编译阶段就根据作用域规则,决定某处代码写的一个名字究竟指的是哪个变量,如果找不到匹配的声明就会报错。
C++中主要有以下几种作用域,按范围从小到大排列:
全局作用域 │ ├── 命名空间作用域 │ │ │ └── 类作用域 │ │ │ └── 函数作用域 │ │ │ └── 块作用域(可以多层嵌套)二、块作用域(局部作用域)
由一对花括号{ }界定的范围,最常见的形式。
voidFunc(){inta=10;// a的作用域从这里开始{intb=20;// b的作用域仅限于这层花括号内std::cout<<a;// 合法,内层能访问外层的a}// std::cout << b; // 编译错误!b已经超出作用域,不可见}// a的作用域到这里结束关键点:if、for、while等控制语句内部隐式创建了新的块作用域;for循环的初始化语句里声明的变量,作用域仅限于该循环体内。
for(inti=0;i<10;i++){}// std::cout << i; // 编译错误,i的作用域仅限于for循环内部三、全局作用域
在所有函数、类、命名空间之外声明的名字,拥有全局作用域,整个文件(乃至整个程序,取决于链接属性)都可见。
intglobal_var=100;// 全局作用域voidFunc(){std::cout<<global_var;// 函数内可以直接访问全局变量}面试常问的关联知识:全局变量默认是外部链接(external linkage),可以被其他.cpp文件通过extern声明后访问;如果加上static修饰,会变成内部链接,只在当前文件内可见(这部分详见前面《static关键字详解》)。
作用域解析运算符:::当局部变量和全局变量同名时,可以用::