我对此非常困惑:
#define prod(x,y) x*y
以下函数调用在控制台中打印11
:
printf("%d",prod(1+2,3+4));
但是当我使用prod(x,y)
作为返回x*y
的函数时,它返回21。
为什么结果不同?我认为#define
应该给prod(x,y) = x*y
。
答案 0 :(得分:2)
运营商优先权正在咬你。
使用
#define prod(x,y) x*y
行
printf("%d",prod(1+2,3+4));
扩展到
printf("%d",1+2*3+4);
请注意,*
的优先级高于+
,因此评估为1 + (2 * 3) + 4
或11
。
<强>解决方案:强>
使用#define
:
#define prod(x,y) ((x)*(y))
该行现在将扩展为:
printf("%d",((1+2)*(3+4)));
围绕整个表达式的额外括号集的目的是使表达式在与评估顺序重要的运算符结合使用时按需要运行。
prod(4,3)/prod(1,2))
扩展为((4)*(3))/((1)*(2))
或6
。如果没有外括号,扩展将为(4)*(3)/(1)*(2)
或24
。
答案 1 :(得分:1)
根据您的宏,prod(1+2,3+4)
已扩展为1+2*3+4
,等于11
。使用parens来修复它:
#define prod(x, y) ((x)*(y))
答案 2 :(得分:1)
根据您的定义
#define prod(x,y) x*y
该行
printf("%d",prod(1+2,3+4));
变为
printf("%d",1+2*3+4);
将评估为
printf("%d",1+6+4);
产生
11
函数以不同方式评估事物。有了这个功能
int prod(int x, int y) { return x*y; }
电话
printf("%d",prod(1+2,3+4));
必须在传递参数之前折叠(评估)参数。这是因为C是&#34;通过值&#34;在它的参数处理方式。甚至在技术上引用的指针也会转换为表示引用的值,并传递这些值。所以呼叫减少到
printf("%d",prod(3,7));
在函数内部变为
return 3*7;
或 返回21
这里有一个有价值的教训。 宏不理解语言。它们只是文本替换,并且它们不会尊重类型,运算符优先级或您花费时间学习的任何其他语言元素。基本上,宏语言是一种不同于C语言的语言,而且比C语言更原始。