使用带参数宏出现意外结果,解析给定C语言代码运行逻辑
代码运行结果解析:为何输出是5 0而非5 3?
核心问题:C宏的文本替换特性导致的陷阱
C语言的宏是纯文本替换,并非函数调用,不会自动处理运算符优先级或语句块逻辑,这是代码出现意外结果的根本原因,具体涉及两个陷阱:
1. big宏的运算符优先级陷阱
#define big(a, b) a > b ? a : b 这个宏没有给参数和整个表达式加括号,当代入3 + big(a, b)时,会被直接替换为:
3 + a > b ? a : b
根据C语言运算符优先级,+的优先级高于>,实际计算顺序为:
- 先计算
3 + a(a=3,结果为6) - 再判断
6 > b(b=5,结果为真) - 三元表达式取
a的值(3)
因此整个if条件((3 + big(a, b)) > b)等价于3 > 5,结果为假,if分支内的代码不会执行。
2. swap宏的语句块陷阱
#define swap(a, b) temp = a; a = b; b = temp; 这个宏包含三条独立语句,但未用花括号{}包裹。替换后代码变为:
if ((3 + a > b ? a : b) > b) temp = a; a = b; b = temp;
由于if后面没有加花括号,只有第一条语句temp = a;属于if分支(且因if条件为假未执行),后面的a = b;和b = temp;会无条件执行:
a = b;→ a被赋值为原b的值5b = temp;→ temp初始值为0,所以b被赋值为0
修正后的代码示例
要避免这些陷阱,宏定义需做两处修改:
- 给
big宏的参数和整个表达式加括号,确保优先级正确 - 给
swap宏的语句块加花括号,保证作为整体执行
修正后的代码:
#include <stdio.h> #define big(a, b) ((a) > (b) ? (a) : (b)) #define swap(a, b) { temp = a; a = b; b = temp; } int main() { int a = 3, b = 5, temp = 0; if ((3 + big(a, b)) > b) swap(a, b); printf("%d %d", a, b); }
此时运行会得到预期的5 3。
内容的提问来源于stack exchange,提问作者Kanishk
相关产品推荐
相关产品推荐

