?变量的定义很多都会被省略, 这里详解.
存储类型? ? 特征修饰? ? 数据类型? ? 变量名
eg:
static? volatile? int? ?value; //静态易变的整型变量value;
- 存储类型: 决定了变量的存储位置
- 特征修饰: 决定了变量的特殊属性
- 数据类型: 决定了变量的存储空间和数据范围
- 变量名称: 决定了变量的引用标识
关键字 | 描述 | 存储位置 |
auto | 自动, 不写默认是这个, 只能修饰局部变量. 临时使用, 不使用的时候会被编译器销毁. | 栈区 |
register | 建议编译器将变量存储在CPU的寄存器中, 但是不一定, 也可能在内存中.?修饰局部变量并且必须是整型. | CPU寄存器 / 内存 |
static | 可以修饰局部变量和全局变量. 生命周期持续整个程序结束. | 存在静态区或数据段 |
extern | 存储在其他文件, 告诉编译器这个变量已经在其他文件申请了一块儿空间, 没必要再申请空间了. | 告诉编译器不用给它申请空间. |
全局变量比较特殊, 初始化过的存在全局数据区, 没有初始化过的存在BSS区
堆是程序员申请, 程序员释放. 栈是编译器申请, 编译器释放.?
关键字 | 描述 |
const | 让修饰的变量只读. |
volatile | 后面详细介绍. |
内存 --> 寄存器(CPU)?
例如:
int a, b;
a = 1;? ?
b = a;? //读取a
- 在内存中(*(&a)) --> 寄存器
- 寄存器 --> 内存(&b)
寄存器(CPU)? --> 内存
例如:
int a, b;
a = 1;? ?
b = a;? //写入b
- 在内存中(*(&a)) --> 寄存器
- 寄存器 --> 内存(&b)
?在计算机工作时, 内存的访问速度远不及CPU的处理速度, 为了提升计算机的整体性能, 在软硬件层面都有相应的机制去优化内存的访问. 方案如下:
//编译器优化, 减少了读取变量的时间
int a = 1, b, c;? //为a, b, c申请内存, 并给a初始化为1
b = a;??????????????// 读取a地址的内容? --> 寄存器x? ? ?寄存器x --> 写入b的内存
c = a;? ? ? ? ? ? ? //寄存器x --> 写入c的内存?
//不优化, 增加了读取变量的时间
volatile int a = 1, b, c;? //为a, b, c申请内存, 并给a初始化为1
b = a;??????????????????????????// 读取a地址的内容? --> 寄存器x? ? ?寄存器x --> 写入b的内存
c = a;? ? ? ? ? ? ? ? ? ? ? ? ? // 读取a地址的内容? --> 寄存器x? ? ?寄存器x --> 写入c的内存?
?volatile的意思是 "易变的" , 在C语言中当使用volatile修饰一个变量时, 即表示这个变量的值随时都有可能发生改变, 因此编译器在编译的时候对该变量的存取操作不能进行优化, 即告诉编译器每次存取该变量的时候都要从内存中去存取而不是使用其之前在寄存器中的备份.
有哪些情况会导致a发生变化, 多线程(RTOS中的任务就是单核多线程的关系), 中断, 硬件寄存器.
优点很明确, 读取的数据都是实时的准确的.
缺点是无法得到编译器的优化, 增加CPU的执行时间, 影响效率, 因此在不需要优化的地方, 不要使用volatile关键字.