如何解决这个表达,考虑到优先级和关联性?

时间:2016-02-24 19:05:18

标签: c

int p=4, s=5;
int m;

m = (p=s) * (p==s);
printf("%d",m);

如何评估此表达式?

m的价值是什么?

在这个例子中,括号如何改变运算符的优先级?

我在Turbo C中得到m = 4.

2 个答案:

答案 0 :(得分:1)

这是一个实际出现在你工作中的代码片段,还是某人给你的作业?

表达式包含两部分:

p=s     /* in this part p's value is assigned */

p==s    /* in this part p's value is used */

所以在我们弄清楚表达式的价值之前,我们必须弄清楚:p的值在使用之前或之后是否设置了?

答案是 - 我会在这里喊一点 - 我们不知道

让我再说一遍。我们根本不知道p的值是在使用之前还是之后设置的。因此,我们无法预测此表达式将评估的值。

现在,您可能会认为优先级会告诉您p在使用之前或之后是否已设置。但事实证明,在这种情况下,优先级不会告诉您p在使用之前或之后是否设置。

您可能会认为关联性会告诉您p在使用之前或之后是否已设置。但事实证明,不,在这种情况下, associativity不会告诉您p在使用之前或之后是否设置了。

最后,您可能认为我错了,优先级和/或关联性必须能够告诉您需要知道的内容,必须有一种方法来确定这个表达式的作用。但事实证明我是对的:没有办法弄清楚这个表达的作用。

您可以编译并尝试它,但这只会告诉您今天使用的编译器如何选择评估它。我向你保证,那里有另一个编译器可以用不同的方式对它进行评估。

你可能会问,哪个编译器是对的?答案是,他们都是正确的(至少,他们都不是错的)。就C语言而言,此表达式是 undefined 。所以没有正确的答案,无论它做什么,你的编译器都没有错。

如果这是您工作中出现的代码,请立即将其删除,找出您真正想要做的事情,并找出一些更清晰明确的表达方式。如果这个代码是一个赋值,你的答案很简单:它是未定义的。 (如果你的导师认为这个表达方式有明确的结果,你就会有一个不知道他在说什么的导师的不幸的位置。)

答案 1 :(得分:0)

您在同一个表达式中多次读取和写入变量p而没有sequence point,这意味着编译器可以按任意顺序自由地计算两个子表达式。

这导致undefined behavior,这意味着程序的行为是不可预测的。