嵌入式与C语言
Volatile
Volatile 英文单词的意思是不稳定的,反复无常的. 在C语言中用volatile的关键字声明变量,就是说这个变量会发生意想不到的变化,每次用这个值的时候都需要重新去读取. 精确的讲应该是优化器用这个变量的时候每次都需要重新去读取这个值,而不能用保存在寄存器里的变量。这是编译器优化器的副作用,因此有些变量要定义为volatile, 特别是在嵌入式编程中, 这是区分嵌入式工程师和C语言工程师之间最基本的一点
那什么样的变量需要是volatile类型呢?
硬件寄存器中断处理程序访问的非自动变量(静态变量,全局变量)多线程共同访问的变量
再稍微深入的讲一些,先提几个问题
一个变量可以既是volatile又是const的吗?why?指针可以使volatile的吗?why?
在讲第一个问题的时候, 先说下const这个关键字
const: 一般人直接说它是常量,更精确的讲法应该是只读,很多函数传入的是个const类型,就是防止你改变它。
const的作用:
一个参数是const就是为了告诉用户这个参数的应用目的,给读代码的人传达很有用的信息合理使用const可以使编译器很自然地保护不希望被改变的参数,防止其被无意修改,减少了bug的出现
回到正题: 答案是肯定的,一个变量既可以是const又是volatile,const 是指程序不应该去修改它,volatile是表明这个变量可能会发生意想不到的改变。只读寄存器就可以是这样的一个例子。
那个一个指针可以使volatile么? 显然是可以的,只是不大常见而已,指针可能会发生意想不到的改变,例如中断程序中修改了一个指向buffer的指针
一个经典的面试题
int square(volatile int *ptr) { return *ptr * *ptr; }上面函数有问题吗? 如果有,错在哪里,怎么改?
square 函数的想法是求一个数的平方,但是*ptr可能会发生意向不到的改变,导致两次读出来的值不一样,比如硬件寄存器的值,那么这个函数返回的就不是一个数的平方了
对于上述函数编译器产生的代码类似于
int square(volatile int *ptr) { int a, b; a = *ptr; b = *ptr; return a * b; // a是第一次读到的值,b是第二次读到的值 }
正确的代码应该是
int square(volatile int *ptr) { int a = *ptr; return a * a; }