为什么分析代码不对?

时间:2015-07-11 05:11:31

标签: c

为什么输出是" 0 -6"而不是" 4 60"? Isn< t = t = 8,l = 2?

#define MAC(a,b) (a<b ? a*b:a-b)
void main (void)
{
   int i=2;
   int j=4;
   int k=MAC(i,j);
   int l=MAC(j,i);
   i=MAC(k+l,k-l);
   j=MAC(k-l,k+l);
   printf("%d %d\n", i,j);
}

2 个答案:

答案 0 :(得分:4)

一个直接的问题。表达式

MAC(k+l,k-l)

变为

(k+l<k-l ? k+l*k-l:k+l-k-l)
           ^^^^^^^

并且,正如您从下划线位看到的那样,由于优先级规则(乘法在加法之前完成),表达式不是您认为的那样。

这可以通过确保宏中的每个参数都带有括号来解决:

#define MAC(a,b) ((a)<(b) ? (a)*(b):(a)-(b))

但如果你传递n++这样的内容仍然会有所帮助,因为它会多次递增。

宏是非常简单的文本替换,众所周知会导致诸如您所看到的问题。我的建议是将MAC变成一个能完全避免问题的正确函数,例如:

int mac (int a, int b) {
    if (a < b)
        return a * b;
    return a - b;
}

答案 1 :(得分:3)

#define MAC(a,b) (a<b ? a*b:a-b)
void main (void)
{
   int i=2;
   int j=4;
   int k= i<j ? i*j:i-j;
   int l= j<i ? j*i:j-i;
   i= k+l<k-l ? k+l*k-l:k+l-k-l;
   j= k-l<k+l ? k-l*k+l:k-l-k+l;
   printf("%d %d\n", i,j);
}

这是您的代码经过预处理后生成的内容。预处理宏在编译之前发生。与编译不同,没有已经发生的变量的符号链接,而是仅仅1到1替换您定义的内容。