在这个问题中,我要问的是以下代码片段是如何工作的,因为它涉及变量的奇怪使用:
while (+(+i--)!=0)
{
i-=i++;
}
console.log(i);
最佳答案
有趣的问题...您已将其标记为 Java、JavaScript 和 C——请注意,虽然这些语言具有相同的语法,但这个问题涉及非常微妙的语义,可能(我不确定)不同语言之间存在差异。
让我们分解一下:
+(+i--)
--
后缀递减运算符是最紧密绑定(bind)的。所以这相当于 +(+(i--))
。因此,这相当于 +(+i)
的值(即 i
),但它在取值后也会递减 i
.它将值与 0 进行比较以查看循环是否应该继续。因此,while (+(+i--)!=0)
等同于以下内容:
while (i-- != 0)
请注意,它还在循环结束时执行 i--
。
在循环中,我相信你有一些未定义的行为,至少在 C 中是这样,因为你在右边引用了 i
,并且还在左边更新了 i
-- 我相信 C 没有定义执行该操作的顺序。因此您的结果可能因编译器而异。 Java,至少,是一致的,所以我会给出 Java 的答案。 i-=i++
等价于i = i - i++
,相当于读取表达式中的所有值,计算表达式的结果,应用后增量,然后分配结果。即:
int t = i - i; // Calculate the result of the expression "i - i++"
i++; // Post-increment i
i = t; // Store the result back
显然,这与编写 i = 0
相同。所以循环体将 i 设置为 0。
因此,循环只执行一次,将 i 设置为 0。然后,它在下一个 while 循环中将 i
递减一次,但检查失败,因为 i
(递减前)== 0。
因此,无论i
的初始值是多少,最终的答案都是-1
。
将所有这些放在一起并编写一个等效的程序:
while (i-- != 0)
{
int t = i - i;
i++;
i = t;
}
console.log(i);
当我在 Java 和 JavaScript 中尝试时,这就是我得到的结果。对于 GCC(C 编译器),它仅在 i
以 0 开始时给出 -1。如果 i
以其他任何方式开始,它会进入无限循环。
那是因为在 GCC 中(不一定是所有 C 编译器),i-=i++
有不同的含义:它首先将存储返回给 i
,然后 做后增量。因此,它等同于:
int t = i - i; // Calculate the result of the expression "i - i++"
i = t; // Store the result back
i++; // Post-increment i
这相当于编写 i = 1
。因此,在第一次迭代中,它将 i
设置为 1,然后在循环中检查 i == 0
是否为 0,如果不是,则继续再次循环,始终将 i
设置为 1。这将永远不会终止,但对于 i
开始为 0 的特殊情况;然后它将始终终止循环并递减 i
(所以你得到 -1
)。
另一个 C 编译器可能会选择像 Java 那样工作。这表明您永远不要编写对同一变量进行赋值和后递增的代码:您永远不知道会发生什么!
编辑:我试图使用 for
循环太聪明了;那不等同。变回 while 循环。
关于javascript - 简单的混淆循环和变量工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6592783/