C语言中的!=符号查询

3
int x = 15 ;
printf ( "\n%d \t %d \t %d", x != 15, x = 20, x < 30 ) ;

代码的输出结果是1 20 1,但我认为应该是0 20 1,因为15 == 15... 我遇到了“x != 15”这一部分的问题。

1
应该是 x==20 而不是 x=20。这会导致您的 x 变量从 15 改变,并实际上使答案有意义。 - Florin Stingaciu
1
你对printf的第三个参数是x = 20,它将x赋值为20。C语言并不保证参数的求值顺序,所以x = 20可能会在x != 15之前被求值。 - vcsjones
3个回答

7

你正在使用 x = 20 为 x 赋新值。

在函数调用的参数列表中,不能假定这些操作以任何特定顺序进行。


我认为他根本没有那个意思。从输出结果来看,他似乎并不惊讶于数字 20。我认为他只是惊讶于在赋值之后还会对 x != 15 进行求值。 - sepp2k
@sepp2k 是的,我仔细阅读了问题和期望的输出,并编辑了我的答案。谢谢。 - pb2q

5

根据我的经验,在大多数C/C++编译器中,大多数参数列表都是从右向左处理的,尽管规范没有对评估顺序做出任何声明。

有了这样的理解,你的参数列表将会按照以下方式进行评估

printf ( "\n%d \t %d \t %d", x != 15, x = 20, x < 30 ) ;

可能按顺序计算

x < 30  => 1
x = 20 (assigns x to 20, returning 20) => 20
x != 15 => 1 (because x is now 20)

如果你的编译器遵循这种评估顺序,那么可以像这样重新排列参数。
printf ( "\n%d \t %d \t %d", x < 30, x = 20, x != 15 ) ;

应该产生,应该得出。
1 20 0

因为比较 x != 15 将在 x 被重新赋值为20之前发生。

这个练习的教训是通常要避免在列表结构中进行赋值(看起来像是"a,b,c,d"),或者至少不要在同一列表结构中读取已赋值的变量,因为你无法保证从右到左还是从左到右进行计算(这取决于编译器)。


直白地说,这种行为是“未定义的”,结果将因编译器而异。 - John Bode
@JohnBode 我以为我已经表达得很清楚了,但是大多数编译器都是使用LR类型解析器实现的,这导致了高效(因此被选择的)从右到左的列表处理。如果没有明确表示无法保证评估顺序,那么感谢您让它变得更加明显。 - Edwin Buck

0

你的代码存在未指定的行为:表达式执行的顺序不一定是按照标准左到右的。 请尝试使用以下代码

int x = 15 ;
int result1 = (x != 15);
int result2 = (x = 20);
int result3 = (x < 30);
printf ( "\n%d \t %d \t %d", result1, result2, result3 ) ;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接