C中while循环条件中的组合赋值运算符
Combined assignment operator in a while loop condition in C
我真的很难理解下面这段代码是如何工作的:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
output: -5, -8, -11, -12
我是说我明白了
while ( --x > -10)
output: -3, -4, -5, -6, -7, -8, -9, -10
和
while (x -= 2)
output: -> infinte loop
单独使用就可以了,但是它们如何与 and 运算符一起工作呢?
我的意思是对于“while (x -= 2)”,条件仅在 x = 2 时才满足,那么 while 循环如何结束而不是像仅使用“while (x -= 2)”时那样无限循环?
您以 -5 开头的事实非常明显:
int x = -2;
while ( --x > -10 && (x -= 2)) {
--x
将 x
从 -2 变为 -3。
x -= 2
将 x
从 -3 变为 -5。
... 所以它更进一步:使用 --x
和 x -= 2
再次递减 3,因此得到类似 -8 和 -11 的值。 (当你达到-11时,你已经检查了“> -10”,那时候是-9)
然后,您再次执行 --x
,将 -11 变为 -12,但您跳出 while 循环并再次打印新值。
编辑,更多说明:
x -= 2
表示 x=x - 2
,这不是某种支票。
代码:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
让代码干燥 运行 并通过循环检查 x 的值 运行。现在,循环有两个条件要满足,即 --x > -10 && (x -= 2)。在第一种情况下,首先减小值,然后检查条件,即 (x = x - 1) > -10。第二个条件总是减 2,即 x = x - 2,因此永远为真。直到两个条件都为真时,循环才会继续。就我所知,第二部分永远是真的。 x的初始值 = -2,
Value of x Output
In the first loop:
is --x > -10, (x -= 2)
True True
x = -3, x = -5 -5
In the sec loop:
is --x > -10, (x -= 2)
True True
x = -6, x = -8 -8
In the third loop:
is --x > -10, (x -= 2)
True True
x = -9, x = -11 -11
In the fourth loop -> exits the while loop since x > -10:
is --x > -10, (x -= 2)
False True
x = -12, x = -14 -12
这是一些“只是为了它而混淆事物”的算法,除了“不要像这样写废话”之外,可以从中学到很少的价值。
它所做的是将值减少 3,但将减少分成两步。首先总是减少 1,然后再减少 2,除非它是循环中的最后一圈。所以 &&
有两个目的:在迭代的最后一次只减少 1,以及一个序列点以允许在同一表达式中对 x
进行两次修改(这是非常糟糕的做法, &&
与否).
对于那些没有参加国际混淆 C 代码竞赛的人,重写类似这样的代码可能更有意义:
int x;
for(x = -5; x >= -11; x -= 3)
{
printf("%d, ", x);
}
printf("%d", x+2);
这也是废话代码,但至少是可读的。作为奖励,它还包含比混淆版本更少的分支。
测试被故意混淆了。以下是步骤:
--x > -10
总是递减 x
并将结果值与 -10
进行比较,如果 x
达到 -10 或以下则跳出循环。
- if
x >= -10
从前面的测试中,(x -= 2)
进一步将 x
的值减 2 并测试结果值是否为非零。 (x -= 2)
为零的 x
的唯一值是 x = 2
。在本例中,x
始终为负,因此此测试始终为真。
从x = -2
开始,迭代次数为:
--x
-> x = -3
,比较为真
(x -= 2)
-> x = -5
, printf
输出 -5
--x
-> x = -6
,比较为真
(x -= 2)
-> x = -8
, printf
输出 -8
--x
-> x = -9
,比较为真
(x -= 2)
-> x = -11
, printf
输出 -11
--x
-> x = -12
,比较为假,退出循环
最后的 printf
输出 -12
代码被不必要地混淆了...
你是对的 while ( x -= 2 )
会导致无限循环。
但是,C 有(所谓的)短路运算符。
因此在表达式 while ( --x > -10 && (x -= 2) )
中,只有当第一项为真时,第二项才会被计算。
因此,当第一项 --x > -10
成立时,第二项 (x -= 2)
也被评估......一旦第一项变为假,第二项就不会被评估,并且循环仅以单个 pre-decrement... 退出,导致您观察到输出。
我真的很难理解下面这段代码是如何工作的:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
output: -5, -8, -11, -12
我是说我明白了
while ( --x > -10)
output: -3, -4, -5, -6, -7, -8, -9, -10
和
while (x -= 2)
output: -> infinte loop
单独使用就可以了,但是它们如何与 and 运算符一起工作呢? 我的意思是对于“while (x -= 2)”,条件仅在 x = 2 时才满足,那么 while 循环如何结束而不是像仅使用“while (x -= 2)”时那样无限循环?
您以 -5 开头的事实非常明显:
int x = -2;
while ( --x > -10 && (x -= 2)) {
--x
将 x
从 -2 变为 -3。
x -= 2
将 x
从 -3 变为 -5。
... 所以它更进一步:使用 --x
和 x -= 2
再次递减 3,因此得到类似 -8 和 -11 的值。 (当你达到-11时,你已经检查了“> -10”,那时候是-9)
然后,您再次执行 --x
,将 -11 变为 -12,但您跳出 while 循环并再次打印新值。
编辑,更多说明:
x -= 2
表示 x=x - 2
,这不是某种支票。
代码:
int x = -2;
while ( --x > -10 && (x -= 2)) {
printf ( " %d," , x ) ;
}
printf ( " %d" , x ) ;
让代码干燥 运行 并通过循环检查 x 的值 运行。现在,循环有两个条件要满足,即 --x > -10 && (x -= 2)。在第一种情况下,首先减小值,然后检查条件,即 (x = x - 1) > -10。第二个条件总是减 2,即 x = x - 2,因此永远为真。直到两个条件都为真时,循环才会继续。就我所知,第二部分永远是真的。 x的初始值 = -2,
Value of x Output
In the first loop:
is --x > -10, (x -= 2)
True True
x = -3, x = -5 -5
In the sec loop:
is --x > -10, (x -= 2)
True True
x = -6, x = -8 -8
In the third loop:
is --x > -10, (x -= 2)
True True
x = -9, x = -11 -11
In the fourth loop -> exits the while loop since x > -10:
is --x > -10, (x -= 2)
False True
x = -12, x = -14 -12
这是一些“只是为了它而混淆事物”的算法,除了“不要像这样写废话”之外,可以从中学到很少的价值。
它所做的是将值减少 3,但将减少分成两步。首先总是减少 1,然后再减少 2,除非它是循环中的最后一圈。所以 &&
有两个目的:在迭代的最后一次只减少 1,以及一个序列点以允许在同一表达式中对 x
进行两次修改(这是非常糟糕的做法, &&
与否).
对于那些没有参加国际混淆 C 代码竞赛的人,重写类似这样的代码可能更有意义:
int x;
for(x = -5; x >= -11; x -= 3)
{
printf("%d, ", x);
}
printf("%d", x+2);
这也是废话代码,但至少是可读的。作为奖励,它还包含比混淆版本更少的分支。
测试被故意混淆了。以下是步骤:
--x > -10
总是递减x
并将结果值与-10
进行比较,如果x
达到 -10 或以下则跳出循环。- if
x >= -10
从前面的测试中,(x -= 2)
进一步将x
的值减 2 并测试结果值是否为非零。(x -= 2)
为零的x
的唯一值是x = 2
。在本例中,x
始终为负,因此此测试始终为真。
从x = -2
开始,迭代次数为:
--x
->x = -3
,比较为真
(x -= 2)
->x = -5
,printf
输出-5
--x
->x = -6
,比较为真
(x -= 2)
->x = -8
,printf
输出-8
--x
->x = -9
,比较为真
(x -= 2)
->x = -11
,printf
输出-11
--x
->x = -12
,比较为假,退出循环最后的
printf
输出-12
代码被不必要地混淆了...
你是对的 while ( x -= 2 )
会导致无限循环。
但是,C 有(所谓的)短路运算符。
因此在表达式 while ( --x > -10 && (x -= 2) )
中,只有当第一项为真时,第二项才会被计算。
因此,当第一项 --x > -10
成立时,第二项 (x -= 2)
也被评估......一旦第一项变为假,第二项就不会被评估,并且循环仅以单个 pre-decrement... 退出,导致您观察到输出。