程序在内存中的分段
- 当程序开始运行后,会加载到内存中,会把内存分成若干段,每一段的功能、权限不同。
- 代码段(text):程序中的二进制指令存储在此段,只读权限。
- 只读段:存储常量、字符串字面值。
- bss段:静态数据段。
- 全局段(data):存储全局变量。
- 栈:局部变量、数组,由操作系统管理,自动申请、释放。
- 堆:由程序员手动管理。
- 注意:代码段、bss段、全局段内存在程序编译完成的时候可以确定,使用size+文件名查看
变量的属性
- 存储位置:变量使用哪一段内存
- 作用域:变量的使用范围
- 生命周期:创建时间~销毁时间
变量的分类
- 全局变量:定义在函数外。
- 局部变量:定义在函数内。
- 块变量:定义在if,for,while等语句块内。
存储位置 | 作用域 | 生命周期 | |
---|---|---|---|
全局变量 | 未初始化存储在bss,初始化存储在全局段 | 整个程序 | main函数执行前就被定义出,程序运行结束后再释放 |
局部变量 | 栈 | 所在的函数内 | 从定义语句开始~函数执行结束,函数每调用一次就会进行一遍定义、释放 |
块变量 | 栈 | 所在语句块的大括号内 | 从定义语句开始~函数执行结束 |
修饰变量的关键字
-
auto:用来定义自动申请内存、自动释放内存的变量(局部、块变量)
不加就代表加,与signed一样 注意:全局变量前不能使用 auto static int num;//错误
-
const:是对变量提供一种保护,但它不一定是常量。
变量一旦初始化后,就不能再显示修改它的值。 const修饰被初始化过的全局变量才是真正的常量,一旦修改就出现段错误,因为编译器把这种全局变量的存储位置划分成了text。
-
static:限制作用域(全局变量、函数)、改变存储位置、延长生命周期(局部、块变量)
修饰变量: 1、全局变量:限制全局变量的作用域,只能在它所在的.c内使用 2、局部、块变量:改变存储位置,由栈改为bss或data,但作用域没有变,并且会延长生命周期。 修饰函数: const int func(void);//const修饰的是函数返回值 static int func(void);//static修饰的是函数 由普通函数变成内部函数,只能在.c文件内调用
-
register
计算机的存储介质:硬盘-》固态硬盘-》内存-》缓存-》寄存器。 申请把变量的存储位置更改为寄存器,因为寄存器不一定成功。 寄存器变量不能取地址,&变量名。
-
volatile:不稳定,易变的,修饰线程间共享的变量,或者硬件编程时使用
如果一个变量的值没有显示的修改,编译器不会再次从内存中读取它的数值,而是直接使用上次读取的结果(优化)。 volatile的功能就是告诉编译器变量的值随时可能发生变化,不要优化它的取值过程(每次用到变量的时候都去内存中获取它大的值)。
int num = 10;
num == num;//永远为真
volatile int num = 10;
num == num;//不永远为真
- extern 声明变量,多个文件中共享全局变量时使用,谁使用谁声明。