【问题标题】:Explain the output of this loop解释这个循环的输出
【发布时间】:2016-05-31 00:56:03
【问题描述】:

这是我在过去的一篇论文中遇到的问题,问题和输出显示在下面,但我不明白这是如何实现的。谁能解释一下。

int main ()
{
    int a[5] = { 1 }, b[] = { 3, -1, 2, 0, 4 };
    for (int i = 0; i<5; i++)
    {
        if (!(a[i] = b[i])) // note: = not ==
            break;
        cout << a[i] << endl;
    }
}

输出:

 3
-1
 2

【问题讨论】:

  • b[i]为0时,那么a[i] = b[i]也为0,!0为真,则执行if语句体。
  • 哪部分不明白?
  • 我不明白我是如何得到输出的?

标签: c++ if-statement for-loop


【解决方案1】:

循环最多运行五次,每次循环时,它将b[i]复制到a[i](a)。如果该副本导致将零放入a[i],则if 语句的条件将为真并且循环将中断。这是因为表达式x = y 的结果是x 的最终值。

在您的情况下,(a[i] = b[i]) 将为零或非零,具体取决于 b[i]。如果是前者,! 将其转换为真值,if 主体运行(break 发生)。如果是后者,你会从! 得到错误,并且循环继续运行。

中断发生在第四个元素上,这就是为什么您只能看到三个输出行。


(a) 您应该知道这是有效的,因为b 的大小隐含为五(您没有显式设置大小,但它使用五个元素进行了初始化)。 a 的大小也是 5,因为您使用 a[5] 指定了它的大小,尽管您只将第一个元素显式初始化为 1(其他元素隐式初始化为零)。

【讨论】:

  • 这是否意味着您可以输出cout&lt;&lt;x = (expression) &lt;&lt;endl;并输出表达式的值,同时将其分配给x
  • @JoelTrauger:差不多。我认为在这种情况下,优先级会评估(expression) &lt;&lt;endl first 并抱怨尝试使用endl 左移。您可以使用cout &lt;&lt; (x = (expression)) &lt;&lt; endl; 修复此优先级。
  • 可能值得编辑以向 OP 解释 int a[5] = { 1 }a 初始化为什么,因为这是提前退出的原因,并且对于不熟悉该大括号初始化程序的情况并不立即显而易见。
  • @user4581301,我会解释的,但这不是提前退出的原因。这完全是由b 中的0 值引起的。
  • Duhhhr.. 你是对的。即使有粗俗的删除评论,我也没有看到单个 =。
【解决方案2】:

我认为要理解这段代码,您需要了解的主要内容是 (a[i] = b[i]) 将被评估为分配给 a[i] 的任何内容,因此当 i 为 3 时,break 将终止您的程序,即是 b[i] 为 0 时。您粘贴的输出也支持这一点。

【讨论】:

    【解决方案3】:

    首先你要了解C++中的类型转换,基本上0转换为布尔类型时为假(你可以从这里看到参考:c++ bool question

    现在程序为循环中的每次迭代做了一件非常简单的事情:

    b[i] 分配给a[i] 并尝试将此int 转换为boolean 类型(隐式转换),看看它是真还是假,它会打印如果为真则为整数,否则中断循环

    因此,您可以看到为什么前 3 个整数被打印出来了,因为它们被分配给 a[i],被转换为 boolean,结果它们变成了真的(是的,-1 变成了也为真,所有非零整数在转换为 boolean)

    时都将变为真

    第 4 个数字是 0,同样它被强制转换为 boolean 并变为 false!所以执行打破了循环,不再循环,不再打印。 (即使第 5 个数字不为零,因为执行已经离开循环,它不会被打印)

    【讨论】:

    • 只是一个挑剔 - 我认为 C++ 标准类似于 C 标准,因为转换是总是显式的 - implicit 的正确术语“类型变形”是转换。
    • @paxdiablo 谢谢,已编辑。很长一段时间以来,我一直通过隐式和显式演员来称呼他们……每天我都学到一些东西:)