就象大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。
volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.
#include "stdio.h"
/*
volatile 指出 i是随时可能发生变化的,
每次使用它的时候必须从i的地址中读取,
因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。
而优化做法是,
由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,
它会自动把上次读的数据放在b中。
而不是重新从i里面读
*/
void main(void)
{
// int i = 10; //debug模式下输出 10、32 release模式下输出10 10 说明进行了代码优化
// //volatile int i = 10; //两种模式下输出的值都进行了改变。volatile定义的变量使编译器不回执行代码优化。
// int a = i;
// printf("%d\n",a);
// // _asm
// {
// mov dword ptr [ebp-4],20h //汇编代码 在编译器检测不到的条件下改变该内存空间所储存的值。
// }
// int b = i;
// printf("%d\n",b);
// int i = 10;
// volatile int *a = &i;
// printf("%d\n",*a);
const volatile int a = 10;
printf("%d\n",a);
getchar();
}
/*
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
int square(volatile int *ptr)
{ return *ptr * *ptr; }
下面是答案: 1). 是的。一个例子是只读的状态寄存器。
它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2). 是的。尽管这并不很常见。一个例子是当一个中断服务子程序修改一个指向一个buffer的指针时。
3). 这段代码是个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,
由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:*/