我们先来看百度到的volatile关键字定义:
volatile提醒编译器它后面所定义的变量随时都有可能改变!因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。
今天遇到了一个基础的有关volatile理解的问题
void main()
{
int k = 3;
printf("%d, %d, %d\n", k, k++, ++k);
}
该程序最终输出
5, 4, 5
可以理解为printf()函数读参的时候从后往前读,所以先执行++k,再执行k++,最后执行k。
++k可以等价于k += 1;
而k++可以等价于int temp = k;k += 1;return temp;
所以该printf最终得到 k, temp, k
由于先经历了++k,所以temp的值是4
显然,该变量k的具体数值是在最后统一取值的
这就导致了"5, 4, 5"的结果,它对应着"k, temp, k"
这就是上文所说的——可能暂时使用寄存器中的值
这显然是反人类的
这个printf()函数从屁股往头读参的阴间方式也就罢了
就这个最后取值这点真的不能忍
于是volatile关键词出现了
它就像一位和蔼的老大哥
负责去告诉编译器,这变量我罩着的,你给劳资悠着点处理
编译器一看这变量傍大款了,乌鸦变凤凰了
自然也就小心处理
于是每次碰到这个变量都会读一次值
like this
void main()
{
volatile int k = 3;
printf("%d, %d, %d\n", k, k++, ++k);
}
这次输出的值变成了
5, 4, 4
see,结果是不是合理了点
那老大哥这么多,变量一定要依靠volatile吗?
也不一定
弱水三千,我只取一瓢
变量随便嫖一个就可以了
like this:
int add(int* a)
{
int temp = *a;
*a += 1;
return temp;
}
void main()
{
int k = 3;
printf("%d, %d, %d\n", k, add(&k), ++k);
}
see,add()函数与k++都会导致返回一个临时值且k = k + 1
但它的结果是
5, 4, 4
可以看到,函数这个大哥编译器也是认的
但前提是变量确实傍上了这个大哥
如果是一个跟k无关的函数,编译器依然会在printf()的最后才统一取值
所以通过这个问题我们知道了
————
傍大款才是当代年轻人唯一的出路(bushi
分享到此,本人小白一枚,有错请指正