javascript - 简单的混淆循环和变量工作

标签 javascript

在这个问题中,我要问的是以下代码片段是如何工作的,因为它涉及变量的奇怪使用:

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/

相关文章:

javascript - Window.open 仅当窗口未打开时

javascript - Mongoose 需要或不需要 { model, Schema } 吗?

javascript - 尝试在 Firefox 中使用 iframe 进行渲染时,如何隐藏 pdf 文件附带的工具栏?

javascript - Google 图表在页面刷新时加载

javascript - 如何声明配置文件变量并将其集成到JS文件中?如何排除/包含构建功能?

javascript - 访问 Jquery 对象 [] 并得到错误

javascript - 将 Ember/Angular 应用程序嵌入到现有站点中

JavaScript 遍历数组

javascript - 以悬停工具提示样式的子导航为中心不起作用

javascript - 使用 javascript 自动计费