需要解释此C程序的输出

时间:2018-02-23 14:09:26

标签: c

#include <stdio.h>

#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X

int main(){
    int a=5, b=10;
    printf("F1=%d, F2=%d\n", F1(a-b), F2(a-b));
    return 0;
}

输出为:F1=5, F2=-15

当然,我认为F1和F2的输出应该相同。括号与输出有什么关系?

3 个答案:

答案 0 :(得分:1)

此程序简单演示了在表达式中使用宏参数时始终需要对其进行括号化的原因。它还说明了为什么一般需要非常小心宏的原因。

  

我认为F1和F2的输出应该是相同的

如果F1F2是函数,而不是宏,则输出确实是相同的。但是,宏是简单的文本替换,因此使用X括号而不加括号的两个表达式是不同的:

F1:

((a-b > 0) ? a-b : -(a-b))

F2:

(a-b > 0) ? a-b : -a-b

请注意,由于缺少括号,F2将一元减号应用于a,而不是(a-b)

这仍然是一个相对简单的宏使用。想象一下当X替换带有副作用的表达式时会遇到的问题,如F2(a++, b--)中所述。

答案 1 :(得分:1)

在玩MACRO时要小心括号()。宏替换后它看起来像这样

 printf("F1=%d, F2=%d\n", ((a-b > 0) ? a-b : -(a-b)), (a-b > 0) ? a-b : -a-b);

现在计算。

F1 => ((a-b > 0) ? a-b : -(a-b))
   => ((5-10 >0) ? 5-10 : -(5-10))
   => ((-5>0 ) false so it prints -(5-10) which is 5

  F2 => (a-b > 0) ? a-b : -a-b
     => (5-10 >0) ? 5-19 : -5-10
     => -5>0 false so it prints -15

答案 2 :(得分:0)

你应该小心宏:

F1(a-b), F2(a-b)

转向:

#define F1(X) ((X > 0) ? X : -(X))
#define F2(X) (X > 0) ? X : -X

int main(){
    int a=5, b=10;
    printf("F1=%d, F2=%d\n", 
                  ((a-b > 0) ? a-b : -(a-b)),
                  (a-b > 0) ? a-b : -a-b ); // < see here
    return 0;
}

在宏中,如果你希望表达式为param,你应该将它们放在括号中 exp