【问题标题】:Question on Infinte Loop in C++C++中的无限循环问题
【发布时间】:2011-09-09 21:08:22
【问题描述】:

这有点好奇。

我正在学习 C++。我被要求重现一个无限循环,例如打印一系列幂的循环:

#include <iostream>

int main()
{
    int powerOfTwo = 1; 

    while (true)
    {
        powerOfTwo *= 2;
        cout << powerOfTwo << endl;
    }
}

结果让我很困扰。例如,使用 Python 解释器,我曾经获得一个有效的无限循环,每次迭代时都会打印 2 的幂(当然,直到 IDE 因超出迭代限制而停止)。使用这个 C++ 程序,我得到一系列 0。但是,如果我将其更改为有限循环,也就是说,我只将条件语句更改为:

(powerOfTwo <= 100)

代码运行良好,打印 2、4、16、...、128。

所以我的问题是:为什么 C++ 中的无限循环会以这种方式工作?为什么它似乎根本不评估 while 主体?

编辑:我正在使用 Code::Blocks 并使用 g++ 进行编译。

【问题讨论】:

  • 我会检查设置了哪些优化标志。
  • 您是在此处发布 实际 代码(例如通过复制和粘贴),还是重新输入?
  • 为我工作。 ideone.com/tJYZA
  • 我这里重新打了一遍,和原来没有区别。

标签: c++ infinite-loop


【解决方案1】:

在无限循环的情况下,您会看到 0,因为 int 在 32 次迭代后溢出到 0 和 0*2 == 0。

查看输出的前几行。 http://ideone.com/zESrn 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 1073741824 -2147483648 0 0 0

【讨论】:

  • 0 之前的最后一个值是 -2147483648,因为他使用的是带符号的数字。但其余的都是正确的。
【解决方案2】:

在 Python 中,整数可以包含任意数量的数字。 C++ 不是这样工作的,它的整数只有有限的精度(通常是 32 位,但这取决于平台)。乘以 2 是通过将整数向左移动一位来实现的。发生的事情是您最初只有整数集中的第一位:

powerOfTwo = 1; // 0x00000001 = 0b00000000000000000000000000000001

循环迭代 31 次后,该位将移动到整数中的最后一个位置。

powerOfTwo = -2147483648; // 0x80000000 = 0b10000000000000000000000000000000

下一次乘以 2,位被移出整数(因为它的精度有限),最终得到零。

powerOfTwo = 0; // 0x00000000 = = 0b00000000000000000000000000000000

从那时起,您就被卡住了,因为 0 * 2 始终为 0。如果您以“慢动作”观看您的程序,您会看到 2 的幂的初始爆发,然后是零的无限循环。

另一方面,在 Python 中,您的代码将按预期工作 - Python 整数可以扩展以容纳任意数量的数字,因此您的单个设置位永远不会“移出整数的末尾”。该数字将继续扩大,因此该位永远不会丢失,并且您永远不会回滚并陷入零。

【讨论】:

  • 很好的解释。我什至没有看到第一个数字,因为输出太快了,所以我假设只有 0。我也没有考虑过整数溢出,因为我不希望 0 而是数据的极限值-type(对我来说是 4 个字节)。谢谢!
【解决方案3】:

实际上它会打印 2 的幂,直到 powerOfTwo 溢出并变为 0。然后 0*2 = 0 等等。 http://ideone.com/XUuHS

【讨论】:

    【解决方案4】:

    I c++ 它的大小有限 - 因此即使出错也能计算

    但是whole true 是这样的

    【讨论】:

      【解决方案5】:

      在 C++ 中,您很快就会导致溢出,您的 int 变量将无法处理大数字。

      int:带符号的 4 个字节可以处理范围 –2,147,483,648 到 2,147,483,647

      正如@freerider 所说,您的编译器可能正在为您优化代码。

      【讨论】:

        【解决方案6】:

        我猜你知道 C、C++ 中的所有数据类型概念,所以你将 powerOfTwo 声明为整数。 所以整数的范围会相应地得到遵循,如果你想要一个连续的循环,你可以使用 char 作为数据类型,通过使用数据转换,你可以为你的函数获得无限循环。

        【讨论】:

          【解决方案7】:

          仔细检查程序的输出。你并没有真正得到无限系列的零。您会得到 32 个数字,然后是无限系列的零。

          三十二个数是二的前三十二次幂:

          1
          2
          4
          8
          ...
          (2 raised to the 30th)
          (2 raised to the 31st)
          0
          0
          0
          

          问题在于 C 如何将数字表示为有限量。由于您的数学量不再可以在 C int 中表示,因此 C 将一些 other 数字放在它的位置。特别是,它将真值以 2^32 为模。但是 2^32 mod 2^32 是零,所以你就是这样。

          【讨论】:

            猜你喜欢
            • 2015-04-29
            • 1970-01-01
            • 1970-01-01
            • 2016-02-21
            • 1970-01-01
            • 1970-01-01
            • 2023-03-28
            • 1970-01-01
            相关资源
            最近更新 更多