嵌入式技术
本期话题
今天聊一道C语言关于宏定义的笔试题:“写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。”
聊一聊
这道题考察的是 C 语言宏定义的知识。我们很容易会想到下边的答案:
#define MIN(a,b) ((a) < (b) ? (a) : (b)) 宏定义会在编译的时候进行替换展开。最好将宏中的参数用括号括起来。这样就避免了当一个表达式同时含有宏定义和其他高优先级运算符时,破坏整个表达式的运算顺序 。 上边的答案解决了一些问题,但是会不会存在其他漏洞呢?如果我们用这个宏进行比较
least = MIN(i++, j++);
替换之后
least = ((i++) < (j++) ? (i++) : (j++)); 无论 i 或者 j 谁小,都会做两次自增运算。导致出现 i 和 j 完成比较后出现错误。 如何消除这种参数变化引起的副作用呢?答案是,用语句表达式来定义这个宏。
注意,语句表达式是 GNU C 对 C语言标准的扩展,允许在一个表达式里内嵌语句。 语句表达式最外面使用小括号()括起来,里面一对大括号 {} 包起来的是代码块,代码块里允许内嵌各种语句。 在语句表达式中用两个临时变量暂时存储这两个参数。
#define MIN_t(x, y) ({
#define MIN_t(type, x, y) ({
#define MIN(x,y) {
一是用来给用户提示一个警告。对于不同类型的指针比较,编译器会发出一个警告,提示两种数据的类型不同。
二是两个数进行比较运算,运算的结果却没有用到,有些编译器可能会给出一个 warning,加一个(void)后,就可以消除这个警告。
好了,到这,整个宏定义面试题的各种解法就分析完毕了。看完之后,是否有所收获呢? 感谢阅读,加油~
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !