繁体   English   中英

你如何评估 z = x- - == y + 1;

[英]How do you evaluate z = x- - == y + 1;

鉴于

int w = 1;
int x = 6;
int y = 5;
int z = 0;
 
z = !z || !x && !y;
printf("%d\n", z);

z = x-- == y + 1;
printf("%d\n", z);

如果 x-- 是 5 并且 y+1 是 6,有人可以解释下面的行如何评估为 1 吗?

z = x-- == y + 1;

表达式x--递减之前计算为x的值。

所以x-- == y + 16 == 5 + 1相同,这是真的,然后将值 1 分配给z

表达方式

z = x-- == y + 1

将被解析为

z = ((x--) == (y + 1))

督察,你的结果比较x--到的结果, y + 1 ,然后将其赋值比较的结果z

的结果x--是的当前值x ; 副作用是x递减。 所以,给定

x == 6
y == 5

然后

x--            == 6
y + 1          == 6
(x-- == y + 1) == 1

所以1被分配给z 在此评估之后, x将等于5

请注意,在这种情况下,C 不会强制从左到右求值 - y + 1可以在x--之前求x-- 另请注意,不必在评估后立即应用--运算符对x的副作用 - 整个事情可以评估为

t1 <- y + 1
t2 <- x
 z <- t2 == t1
 x <- x - 1

要么

t1 <- x
t2 <- y + 1
 x <- x - 1
 z <- t1 == t2

或任何其他订单。 x的更新和对z的分配可以以任何顺序发生,甚至同时发生(交错或并行)。

虽然惯用的 C 通常有点令人头疼,但这有点太过分了。 作为学习运算符优先级和副作用的学术练习,这很好(不是很好),但是任何在生产代码中这样做的人都可能会在代码审查中对此感到悲伤。 如果没有其他问题,它不能很好地扫描 - 只需添加一些括号(就像我上面所做的那样)将极大地帮助提高可读性。

来自 C 标准(6.5.2.4 后缀自增和自减运算符)

2 后缀++运算符的结果是操作数的值。 作为副作用,操作数对象的值会增加(即,将适当类型的值 1 添加到其中)。

3 后缀--运算符与后缀++运算符类似,只是操作数的值是递减的(即减去相应类型的值1)

因此在这个表达式语句中

z = x-- == y + 1;

可以等效地重写为

z = ( x-- ) == ( y + 1 );

后缀递减表达式x--的值是递减前变量x的值。 即表达式的值等于6

表达式y + 1值也等于6因为y的值等于5

最后(C 标准,6.5.9 相等运算符)

3 ==(等于)和 !=(不等于)运算符类似于关系运算符,只是它们的优先级较低。108)如果指定的关系为真,则每个运算符都产生 1,如果指定的关系为假,则产生 0。 结果的类型为 int。 对于任何一对操作数,只有一个关系为真

因此,当表达式x--的值等于表达式y + 1的值时,变量z的值为1

您可以通过以下方式获得预期的结果保持后缀递减运算符

z = ( x--, x == y + 1 );

通过插入逗号运算符。 在这种情况下,在逗号运算符之后有一个序列点,这意味着在逗号运算符的第二个操作数中x == y + 1 x将已经等于 5。

另一方面,如果你会写这样的表达式

z = --x == y + 1;

其中使用一元减量运算符代替后缀减量运算符——那么表达式 --x 的值将等于5 (一元减量运算符的值是其减量后的操作数的值)。 在这种情况下,变量 z 的值为0因为5不等于6 (表达式y + 1的值)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM