volatile
volatile原意是“易变的”,在嵌入式环境中用volatile关键字声明的变量,在每次对其值进行引用的时候都会从原始地址取值。由于该值“易变”的特性所以,针对其的任何赋值或者获取值操作都会被执行(而不会被优化)。由于这个特性,所以该关键字在嵌入式编译环境中经常用来消除编译器的优化,可以分为以下三种情景:
- 中断服务程序中修改的供其它程序检测的变量需要加volatile;
static int i=0;
void main(void)
{
while(1)
{
if (i>0) i++;
}
}
void isr()
{
i = 1;
}
//编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作
//然后每次if判断都只使用这个寄存器里面的“i副本”,导致dosomething永远也不会被调用。
//如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)
- 多任务环境下各任务间共享的变量应该加volatile;
- 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
typedef
typedef是一个高级数据特性,可以为某一类型自定义名称。这方面与#define类似,但是两者有不同:
- typedef用来定义类型的别名,定义与平台无关的数据类型,与struct的结合使用等。
define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。
- 关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。
define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。
-
define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。
typedef有自己的作用域。
- 二者修饰指针类型时,作用不同。
typedef int * pint;
#define PINT int *
int i1 = 1, i2 = 2;
const pint p1 = &i1; //p不可更改,p指向的内容可以更改,相当于 int * const p;
const PINT p2 = &i2; //p可以更改,p指向的内容不能更改,相当于 const int *p;或 int const *p;
pint s1, s2; //s1和s2都是int型指针
PINT s3, s4; //相当于int * s3,s4;只有一个是指针。
网友评论