vlambda博客
学习文章列表

C语言两种类型限定词const和volatile

「今天是学习C语言第 35 天」


当你选择了一种语言,意味着你还选择了一组技术、一个社区。——Joshua Bloch

# 类型限定词

C89标准规定了两种类型限定词,在进行变量类型声明时,写在前面。

例如:

const int i;

volatile int i;

其中:

const:英文是常数常量的意思,限定声明的变量是不可修改的常量,该变量在第一次初始化后,始终保持值不变。


volatile:英文是易变的、不稳定的,限定声明的变量值是经常可能会变化的、不稳定的,因此编译器不应该对该类型的变量访问和操作进行优化或重新排序。


# const

const修饰的变量也称为只读变量,该变量一经声明和定义,值在程序运行过程无法被赋值修改。


例如:正确用法

const int MAX = 100 ;

int str[MAX];

声明常量MAX,一般常量使用大写字母表示,常量值是100,一般可以作为数组长度之类使用。


例如:以下是错误使用方式

#include <stdio.h>const int i; int main(void){i = 1;
const int j ;j = 2; return 0;}
输出:编译出错,提示非法给只读变量i和j赋值修改。

# volatile

易变型变量,是指该变量的值会被意外改变,编译器不应该做优化。

正常情况下,编译器一般在不影响程序执行的结果情况下,对程序操作进行优化或重新排序。


举例说明:

例如你自己的一个银行账号今天你用手机或去银行网点查余额显示1000元,那么明天、后天,你需要知道余额,不用去查了,如果这两天花钱了,你在1000的基础上进行加减运算就可以得出余额,如果这两天没有花钱,直接靠记忆(缓存)知道余额还是1000。

以上计算的前提是这个银行账号只有你自己知道和在用,家人不知道和不用该卡。如果该银行账号是父母给你的副卡,父母和你共享使用,父母在明天、后天给你打了这个月的生活费1000,那么你就必须再查一遍余额才能知道。这种需要使用volatile修饰余额变量以后,告诉程序每次都只能去查余额才能知道,因为余额随意会被其他人改变,不仅仅是自己。


例如:优化,减少操作

int i,j;

i = 1;

j = 2;

i = 2;

j = 3;

...

解析:编译器可能直接优化,省略i=1;j=2;这两步赋值操作,因为不影响结果。

如果对变量i,j加上volatile关键字声明,以上操作不做优化。


例如:优化,每次访问缓存或寄存器的数值

int i = 1;

while(i)

{

   // 执行操作1

}

// 执行操作2

解析:实际编译器优化时,第一次从内存读取到i的值1,放入缓存或寄存器中,以后每次都访问缓存或寄存器,导致如果内存的i值发生变化,并不能及时退出循环。


在简单的非并发、单一线程的C语言程序环境中,这种优化都是没问题的,不影响结果,但在以下复杂应用场景下面,如果某变量的值可能被其它程序、外在条件改变时,应使用volatile。

  • - 该变量的值其实是存储映射输入输出端口的对象,也就是代表着硬件的状态(硬件一般会统一编址到内存空间,硬件的状态是受外在条件改变的)

  • - 多线程、多并发、异步中断服务的场景下,该变量的值是共享的。

注意:volatile修饰的变量的特点是该变量是共享的,也就是可以由多个程序同时访问的,后续学习完操作系统、嵌入式编程等课程就会更加容易理解。


---------- End ----------


往期精彩推荐:





「喜欢C请赏个 赞    点击右下角 在看」