[英]Combined assignment operator in a while loop condition in C
I really have a hard time understanding how the following piece of code works:我真的很难理解以下代码是如何工作的:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
output: -5, -8, -11, -12
I mean I get what我的意思是我得到了什么
while ( --x > -10)
output: -3, -4, -5, -6, -7, -8, -9, -10
and和
while (x -= 2)
output: -> infinte loop
alone would do, but how do they work with the and operator?单独就可以,但是它们如何与 and 运算符一起工作? I mean for "while (x -= 2)" the condition is only met when x = 2, so how can the while loop even end and not go infinite like it does when only "while (x -= 2)" is used?
我的意思是“while (x -= 2)”的条件只有在 x = 2 时才会满足,所以 while 循环如何才能结束而不是 go 无限,就像只使用“while (x -= 2)”时那样?
The fact that you start with -5 is quite obvious:以 -5 开头的事实非常明显:
int x = -2;
while ( --x > -10 && (x -= 2)) {
--x
turns x
from -2 into -3. --x
将x
从 -2 变为 -3。
x -= 2
turns x
from -3 into -5. x -= 2
将x
从 -3 变为 -5。
... and so it goes further: using --x
and x -= 2
you decrement again by 3, so you get values like -8 and -11. ...所以它更进一步:使用
--x
和x -= 2
你再次减 3,所以你得到像 -8 和 -11 这样的值。 (When you reach -11, you already checked for "> -10", which was -9 at that moment) (当您达到 -11 时,您已经检查了“> -10”,当时是 -9)
Then, again you do --x
, turning -11 into -12, but you jump out of the while loop and you print that new value again.然后,您再次执行
--x
,将 -11 变为 -12,但您跳出 while 循环并再次打印该新值。
Edit, more clarification:编辑,更多说明:
x -= 2
means x=x - 2
, it's not some kind of a check. x -= 2
表示x=x - 2
,这不是某种检查。
Value of x Output
In the first loop:
x = -3, x = -5 -5
In the sec loop:
x = -6, x = -8 -8
In the third loop:
x = -9, x = -11 -11
In the fourth loop -> exits the while loop since x > -10:
x = -12, x = -14 -12
The test is purposely obfuscated.测试是故意混淆的。 Here are the steps:
以下是步骤:
--x > -10
always decrements x
and compares the resulting value to -10
, breaking from the loop if x
reaches -10 or below. --x > -10
总是递减x
并将结果值与-10
进行比较,如果x
达到 -10 或更低,则退出循环。x >= -10
from the previous test, (x -= 2)
further decreases the value of x
by 2 and tests whether the resulting value is non zero.x >= -10
,则(x -= 2)
进一步将x
的值减少 2 并测试结果值是否非零。 The only value of x
for which (x -= 2)
is zero is x = 2
. (x -= 2)
为零的x
的唯一值是x = 2
。 In the present case, x
is always negative so this test is always true.x
始终为负,因此该测试始终为真。 starting from x = -2
, the iterations are:从
x = -2
开始,迭代是:
--x
-> x = -3
, the comparison is true --x
-> x = -3
,比较为真(x -= 2)
-> x = -5
, printf
outputs -5
(x -= 2)
-> x = -5
, printf
输出-5
--x
-> x = -6
, the comparison is true --x
-> x = -6
,比较为真(x -= 2)
-> x = -8
, printf
outputs -8
(x -= 2)
-> x = -8
, printf
输出-8
--x
-> x = -9
, the comparison is true --x
-> x = -9
,比较为真(x -= 2)
-> x = -11
, printf
outputs -11
(x -= 2)
-> x = -11
, printf
输出-11
--x
-> x = -12
, the comparison is false, the loop is exited --x
-> x = -12
,比较为假,退出循环
the final printf
outputs -12
最后的
printf
输出-12
The code is unnecessarily obfuscated...代码被不必要地混淆了......
You are right that while ( x -= 2 )
would result in an infinite loop.没错,
while ( x -= 2 )
会导致无限循环。
However, C has (what are known as) short circuit operators .然而,C 有(所谓的)短路算子。
Thus in the expression while ( --x > -10 && (x -= 2) )
the second term is only evaluated when the first term is true.因此,在表达式
while ( --x > -10 && (x -= 2) )
中,仅当第一项为真时才计算第二项。
Therefore, while the first term --x > -10
holds true, the second term (x -= 2)
is also evaluated... once the first term becomes false, the second term is not evaluated, and the loop exits with just the single pre-decrement... resulting in the output you observe.因此,虽然第一项
--x > -10
成立,但第二项(x -= 2)
也被计算...一旦第一项变为假,第二项就不会被计算,并且循环仅退出单个预减量...导致您观察到的 output 。
This is some "obfuscate things just for the heck of it" algorithm, from which very little of value can be learnt, except "don't write crap like this".这是一些“只是为了它而混淆事物”的算法,从中可以学到很少的价值,除了“不要像这样写废话”。
What it does is to decrease the value by 3, but split that decrease in two steps.它所做的是将值减少 3,但将减少分成两步。 First always decrease by 1 and then by 2 more, unless it's the very last lap in the loop.
首先总是减少 1,然后再减少 2,除非它是循环的最后一圈。 So the
&&
serves two purposes: to only decrease by 1 the last time of the iteration, as well as a sequence point to allow two modifications of x
in the same expression (which is very bad practice, &&
or not).所以
&&
有两个目的:在最后一次迭代中只减少 1,以及允许在同一个表达式中对x
进行两次修改的序列点(这是非常糟糕的做法, &&
或不是)。
For those not participating in the International Obfuscated C Code Contest, it might make more sense to rewrite the code similar to this:对于那些没有参加国际混淆 C 代码竞赛的人来说,重写类似这样的代码可能更有意义:
int x;
for(x = -5; x >= -11; x -= 3)
{
printf("%d, ", x);
}
printf("%d", x+2);
This is also nonsense code but at least it is readable.这也是无意义的代码,但至少它是可读的。 As a bonus, it also contains less branching than the obfuscated version.
作为奖励,它还包含比混淆版本更少的分支。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.