我无法理解为什么以下代码打印2而不是1 ...
#include <stdio.h>
#define ABS(x) ((x) < 0) ? -(x) : (x)
int main()
{
printf("%d", ABS(ABS(-2)-(ABS(-3))));
return 0;
}
这个问题在我们的考试中,我回答输出是1但是在编译之后我得到2 ...有人请说明实际表达的内容......提前致谢。
答案 0 :(得分:3)
你忘记了外括号,试试这个:
#define ABS(x) (((x) < 0) ? -(x) : (x))
答案 1 :(得分:2)
括号有问题。如果展开宏,您将获得复杂的嵌套三元运算,其值为2
(请参阅更新中的扩展)。为了得到一个理想的结果用括号围绕宏。
更新:手动扩展:
ABS(ABS(-2)-(ABS(-3)))
扩展为:
((ABS(-2)-(ABS(-3))) < 0) ? -(ABS(-2)-(ABS(-3))) : (ABS(-2)-(ABS(-3)))
ABS(-3)
在任何地方都被括号括起来,因此可以安全地评估3
,因此无需展开它。所以我们最终:
(( ((-2) < 0) ? -(-2) : (-2) - 3) < 0) ? -(ABS(-2)-3) : (ABS(-2)-3)
(ABS(-2)-3)
将扩展为
((-2) < 0) ? -(-2) : (-2) - 3 = 2
评估整体:
(( true ? 2 : -5 < 0) ? -2 : 2
或
(2 < 0) ? -2 : 2 = 2
这是观察到的结果,希望它是可以跟随的。
这是eno
答案 2 :(得分:1)
#include <stdio.h>
#define ABS(x) ((x) < 0) ? -(x) : (x))
int main()
{
printf( "%d", ABS( ABS(-2) - ABS(-3) ) );
return 0;
}
您忘记了)
中的右括号#define
。
此外,return
必须为小写
我放置了空格,因此您可以更清楚地看到分组。
答案 3 :(得分:1)
gcc预处理器解决了这个问题:
printf("%d\n", ABS(ABS(-2)-(ABS(-3))));
到此:
printf("%d\n", ((((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) < 0) ? -(((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) : (((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))));
检查你的自己
答案 4 :(得分:1)
您需要围绕ABS
定义的表达式使用括号。而不是
#define ABS(x) ((x) < 0) ? -(x) : (x)
你需要:
#define ABS(x) (((x) < 0) ? -(x) : (x))
^----------------------^
如果不这样,表达式ABS(ABS(-2)-(ABS(-3)))
将扩展为:
((((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) < 0) ? -(((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) : (((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3)))
分析这将是一个很难理解出错的地方。但是,如果您查看表达式的开头,您将看到第一个术语将进入第二个术语。
((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ...
^^ (-2) Runs into the next term
表达式的价值难以预测。如果在宏定义的表达式周围添加括号,您将看到:
( (((-2) < 0) ? -(-2) : (-2)) - ( (((-3) < 0) ...
^ ------ one term ------- ^ There is no running in to the next term.
答案 5 :(得分:1)
让我们手动扩展这个宏:
ABS(-3) == ((-3) < 0) ? -(-3) : (-3)
ABS(-2) == ((-2) < 0) ? -(-2) : (-2)
ABS(-2) - ABS(-3) ==
((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)
现在我们遇到了一个问题:二进制-
的优先级高于?:
,因此上面的解析为:
((-2) < 0) ? -(-2) :
((-2) - ((-3) < 0) ? -(-3) : (-3))
由于(-2) < 0
为真,我们会评估-(-2)
。然后:
ABS( ABS(-2) - ABS(-3) ) ==
((((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) < 0 ?
-(((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) :
(((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3))
我们已经建立了
((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)
评估为2
,因此表达式为
(((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3))
得到评估,猜猜是什么?它评估为2
。
您需要做的是更改您的宏,如下所示:
ABS(x) ( (x) < 0 ? -(x) : (x) )
然后一切都扩展为
ABS(-3) == ((-3) < 0 ? -(-3) : (-3))
ABS(-2) == ((-2) < 0 ? -(-2) : (-2))
ABS(-2) - ABS(-3) ==
((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3))
ABS(ABS(-2) - ABS(-3)) ==
(((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3)) < 0 ?
-(((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3))) :
((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3))
这次,
(((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3))
评估为-1
。
其余部分应该从这里清楚。
出于这个原因,您应该总是将表达式宏体包装在外部括号中。