2021-06-14

2021-06-14  本文已影响0人  CodingEleven

volatile

volatile原意是“易变的”,在嵌入式环境中用volatile关键字声明的变量,在每次对其值进行引用的时候都会从原始地址取值。由于该值“易变”的特性所以,针对其的任何赋值或者获取值操作都会被执行(而不会被优化)。由于这个特性,所以该关键字在嵌入式编译环境中经常用来消除编译器的优化,可以分为以下三种情景:

  1. 中断服务程序中修改的供其它程序检测的变量需要加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修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)
  1. 多任务环境下各任务间共享的变量应该加volatile;
  2. 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

typedef

typedef是一个高级数据特性,可以为某一类型自定义名称。这方面与#define类似,但是两者有不同:

  1. typedef用来定义类型的别名,定义与平台无关的数据类型,与struct的结合使用等。

define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

  1. 关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。

define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。

  1. define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。

typedef有自己的作用域。

  1. 二者修饰指针类型时,作用不同。
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;只有一个是指针。
上一篇下一篇

猜你喜欢

热点阅读