关键字volatile有什么含意?并给出三个不同的例子。
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是[URL=http://www.dzsc.com/stock-ic/2SK1740-5-TB.html]2SK1740-5-TB[/URL],优化器在用到这个变量时必须每次都小心地重新读取这个变量的值[URL=http://www.dzsc.com/stock-ic/PMB27201-V1.4.html]PMB27201-V1.4[/URL],而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
1)是的。一个例子是只读的状态寄存器[URL=http://www.dzsc.com/stock-ic/LC78835M_KM.html]LC78835M/KM[/URL]。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2); 是的。尽管这并不很常见[URL=http://www.dzsc.com/stock-ic/SN84LS02N.html]SN84LS02N[/URL]。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
中断服务子程序(ISR),
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}
1) ISR 不能返回一个值[URL=http://www.dzsc.com/stock-ic/MP430.html]MP430[/URL]
。如果你不懂这个,那么你不会被雇用的。
2) ISR 不能传递参数[URL=http://www.dzsc.com/stock-ic/R5306-18.html]R5306-18[/URL]。如果你没有看到这一点,你被雇用的机会等同第一项。
3) 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
4) 与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点[URL=http://www.dzsc.com/stock-ic/LTC2625IGN-1PBF.html]LTC2625IGN-1PBF[/URL],那么你的被雇用前景越来越光明了。
2) 15 Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?
这是一个非常微妙的问题[URL=http://www.dzsc.com/stock-ic/SN74ALS756-1N.html]SN74ALS756-1N[/URL]
,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2;
tPS p3,p4;
第一个扩展为
struct s * p1, p2;
上面的代码定义p1为一个指向结构的指[URL=http://www.dzsc.com/stock-ic/1645T48PEA12V.html]1645T48PEA12V[/URL],p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。