当用作较大数学表达式的一部分时,使用宏导致错误输出 – 为什么会发生这种情况?
这是一个正常的C例行程序,我在一些问题库中找到了。 如下所示:
#define CUBE(p) p*p*p main() { int k; k = 27 / CUBE(3); printf("%d", k); }
根据我的理解和知识,K的值应为1,因为在预处理期间CUBE(3)将被3 * 3 * 3替换,并且在随后的编译之后它将给出值1,但它已显示值81这让我很想知道它是怎么发生的。
任何人都可以certificate上面这个问题的答案是正确的。
预处理器应正确括号。 替换为
#define CUBE(p) ((p)*(p)*(p))
并看到。
预处理器只是替代
CUBE(3)
同
3*3*3
所以你最终得到:
k=27/3*3*3
其中,从左到右评估运营商优先权,实际上是81。
如果在宏周围添加括号,您应该会发现结果是正确的:
#define CUBE(p) (p*p*p)
用括号括起p
每个实例会更好,如:
#define CUBE(p) ((p)*(p)*(p))
这将允许您正确地将表达式传递给宏(例如, 1 + 2
)。
由于运算符优先级27/3*3*3 = 81
你可以用:
inline int cube(int p) { return p*p*p; }
C宏进行文本替换(即它相当于复制和粘贴代码)。 所以你的代码来自:
k=27/CUBE(3);
至
k=27/3*3*3;
除法和乘法具有相同的优先级并具有从左到右的关联性,因此将其解析为:
k=((27/3)*3)*3;
这是9 * 3 * 3 = 81。
这就是为什么C宏应该总是通过自由使用括号来定义:
#define CUBE(p) ((p) * (p) * (p))
有关更多信息,请参阅comp.lang.c常见问题解答中的http://c-faq.com/cpp/safemacros.html 。
因为宏是文本替换,所以它适用于:
k = 27 / 3 * 3 * 3;
由于乘法和除法从左到右发生,因此可以解决:
k = ((27 / 3) * 3) * 3;
所以,你想以两种方式改变它:
#define CUBE(p) ((p)*(p)*(p))
外括号使得乘法在任何其他操作之前完成。
个别p周围的括号适用于以下情况:
CUBE(1 + 2);
如果没有这些内部括号,运算符优先级将使您失望。
您的宏未受保护。 尝试
#define CUBE(p) ((p)*(p)*(p))
目前的宏扩大到了
k=27/3*3*3
这是((27/3)* 3)* 3
k=27/CUBE(3); => k=27/3 * 3 * 3;
你看到了吗? CUBE应该像这样定义:
#define CUBE(p) ((p)*(p)*(p))
当你做宏时,你必须小心如何放置括号。 在这种情况下,你没有任何,所以表达式变为27/3 * 3 * 3,由/和*的优先规则变为(27/3)* 3 * 3。
27/3 * 3 * 3 = 9 * 3 * 3 = 81?
两个/和*运算符具有相同的优先级。 首先要执行3 * 3 * 3,你可以将它们括在括号中。
#include #define CUBE(p) p*p*p int main () { int k; k=27/(CUBE(3)); printf("%d",k); return 0; }
#define CUBE(p) p*p*p main() { int k; k=27/CUBE(3); printf("%d",k); }
根据我的理解和知识,K的值应为1,因为在预处理期间CUBE(3)将被3 * 3 * 3替换
是
并且在随后的编译之后,它将给出值1,但是它显示了81的值,这使我好奇地知道它是如何发生的。
没有,
k= 27/3*3*3 =(((27/3)*3)*3) (The precedence of `*` and `/` are same but the associativity is from left to right) =((9*3)*3) =81
用#define CUBE(p) p*p*p
替换#define CUBE(p) p*p*p
#define CUBE(p) ((p)*(p)*(p))
它是实现运算符的关联性和优先级的方式。 当表达式扩展时它现在变为27/3 * 3 * 3而不是27 /(3 * 3 * 3) ,除法和乘法在C中具有相同的优先级,但两者的关联性从左到右。 所以它可以显示为:(27/3)* 3 * 3,如果你还记得BODMAS(Bracket Off Division Multiplication Addition Subtraction)的旧算术规则, 它也会等于(9 * 3)* 3 = 81是优先顺序,然后我们首先进行除法,然后进行乘法运算。 所以我们再次以27/3 * 3 * 3得到81的答案。
您的答案是:81说明:在步骤k = 27 /立方体(3)立方体(3)被预处理器替换为3 * 3 * 3.然后上述语句变为k = 27/3 * 3 * 3 27/3表达式由c编译器(运算符优先级)评估,结果为(27/3):9语句k = 27/3 * 3 * 3变为k = 9 * 3 * 3; 上述陈述的结果是81: