每日福利
“精通C语言,不错嘛!” 面试官道
“呵呵,略懂!” 某小伙儿
“写个回调函数呗!”
“回调…有点忘了…”
“咳咳无妨。讲讲cv限定词吧”
“我…也不大记得…”
“那你写个精通啥意思?”
“给…给我个机会,我还企业一片蓝天!”
“滚!”
以上对话虽然是杜撰的,但也绝非空穴来风,的的确确有类似的面试场景,我们不要笑话别人,也不能允许以后被别人笑话。比如上述对话中提到的cv限定词,现在就得立刻马上就地正法!绝不姑息!不然以后还真的遇到了笔试面试,笑话就落到自己头上了。
啥叫cv限定词辣么牛B哄哄呢?其实就是const和volatile。
先来说第一个关键字:const。这个关键字是C语言中最不靠谱最名不副实的一个关键字,const本身是constant的缩写,本意是常量,但是C语言中有3种使用和定义常量的方法,const不在此列。而你去阅读C语言相关的文章和书籍你会发现,这个关键字的作用有个特别别扭的定义:用来定义只读的变量,这句话就像说画一个方形的圆圈一样充满悖论。但的确如此,下面用几行代码来说明这个问题。
int const a = 100; a = 200; // 这是错误的,因为 a 是只读的
int const b = 100; switch(...) { case b: // 这是错误的,因为 b 不是常量 ... ... }
上面的两段小代码刚好说明了const的两个侧面,他的确是一个只读的变量,一个怪胎。const在C语言中只有一种有实际意义的用法,那就是定义指针:
int const * p = &n;
上述指针p跟普通的指针的区别在于:你无法通过p来修改目标n,这样对于这个指针的使用者而言就起到了保护原数据的作用。
另外还有个volatile,这个关键字在应用程序中不常见,但在系统的底层代码中尤为常见,特别是跟硬件寄存器相关的代码片段中。这个英文单词的本意是易变,回归到程序上来理解,就是可能有多种途径来方位到这个变量,因此我们的编译系统不能想当然地去优化被volatile修饰的代码,比如:
#define *( (volatile unsigned long *)0x080AFF18 ) WDCONFIG
编译系统在处理WDCONFIG的时候,简单地讲就是不能用类似缓存这样的机制来提高效率,因为一旦缓存起来,数据就有可能因为多处访问都导致不一致。跟这个关键字恰好相反的是另一个关键字:restrict。被他修饰的变量的访问途径是唯一的,那么编译系统就可以尽可能地地优化了,比如:
char * restrict p = malloc(100);
以上的代码表示 p 是唯一能访问那块内存的指针,因此这块内存就可以尽可能地缓存起来提高效率。