C语言中几个特殊的关键词 在这里我只是简单地介绍一下volatile、__packed和const的作用,省得我们在看到它们的时候不知所措。
volatile关键词
volatile的中文意思是“易挥发的”,它主要是给编译器提个醒,告诉编译器对于volatile变量不要轻易的进行优化,因为在程序运行过程中这个值会被其他的任务或硬件改变。在编译器中对于语句通常会做一些优化,例如有如下程序:
bool bExit == FALSE;
…
for(;;)
{
…
if(bExit)
{
break;
}
}
假设现在有另一个任务或线程通过bExit来控制程序的退出。如果此时变量不使用volatile关键字说明的话,编译时就会对if(bExit)进行优化,不再在每一次for循环中判断bExit了,这样就会导致程序运行错误。因此,此时应使用volatile关键字说明bExit变量,这样编译器就不会做这样的优化了。
__packed关键词
__packed用来声明结构体采用单字节偏移。并不是所有的编译器都支持这个选项。使用__packed声明的结构体会压缩空间。例如有下面一个结构体:
struct _Test{
int a;
char b;
char c;
int d;
}Test;
如果不使用__packed声明,在ARM编译器中sizeof(Test)等于12(在ARM编译器中是4字节偏移,int也是4字节变量)。加入__packed说明后,sizeof(Test)等于10,编译器会压缩Test结构体中b、c和d变量之间的padding字节。对比示意图如下:
int a;
(4 B)
char b;(1B)
char c;(1B)
intd;
(4 B)
int a;
(4 B)
char b;(1B)
char c;(1B)
int d;
(4 B)
Padding
(2B)
无__packed
有__packed
图 结构体内存映射
从这个图中可以看出,经过__packed说明之后的结构体,相对于没有使用__packed说明的节省了2字节的padding存储空间,实际上这给我们提供了一种紧凑数据的方法。
const关键词
使用const的好处在于它允许指定一种语意上的约束——某种数据不能被修改——编译器具体来实施这种约束。通过const,我们可以告知编译器和其他程序员某个值要保持不变。只要是这种情况,我们就要明确地使用const ,因为这样做就可以借助编译器的帮助确保这种约束不被破坏。
对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const,还有,两者都不指定为const:
char *p = "hello"; // 非const指针, 非const数据
const char *p = "hello"; // 顶一下