当用作较大数学表达式的一部分时,使用宏导致错误输出 – 为什么会发生这种情况?

这是一个正常的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: