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)) {

--xx 从 -2 变为 -3。
x -= 2x 从 -3 变为 -5。

... 所以它更进一步:使用 --xx -= 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... 退出,导致您观察到输出。