我不明白这个infini循环

时间:2015-03-09 10:11:13

标签: c++ while-loop

我很抱歉,如果这似乎很容易修复,但我在做什么应该是一个简单的while循环时遇到了一些奇怪的事情。任何人都可以帮我解决为什么这个循环会永远持续下去吗?

此代码是为这个简单的练习而设计的:

  

有一个古老的故事,皇帝想要感谢发明者   国际象棋比赛,并要求发明人说出他的奖励。该   发明家要求为第一个广场提供一粒米,为第一个广场提供2粒米   第二,第四,4,依此类推,每64个加倍   广场。这可能听起来不大,但是没有多少米饭   帝国!写一个程序来计算   需要多少个方块才能给发明者至少1000粒大米,至少1,000,000粒,至少1,000,000,000   谷物。当然,你需要一个循环,并且可能需要一个int   跟踪你在哪个方格,一个int来保持谷物的数量   在当前的广场上,和一个int来跟踪所有的谷物   以前的广场。我们建议你写下你所有人的价值   循环的每次迭代的变量,以便您可以看到什么   继续。

这是我的代码:

#include <iostream>

using namespace std;

int main()
{
  double square = 2;
  double rice = 2;
  while (rice < 1000000000, rice *= 2)
  {
    cout << "There is " << rice << " pieces of rice that the inventor owns at square " 
         << square << endl;
    cout << "\n";
    square++;
  }
}

如果这有什么不同,我重写了这段代码以适应java并在eclipse上得到了同样的东西。

7 个答案:

答案 0 :(得分:4)

问题出在while (rice < 1000000000, rice *= 2)条件下。如果用逗号分隔多个语句,则整个语句的结果等于最后一个语句的结果。所以你实际上while (rice *= 2)肯定是真的。

答案 1 :(得分:3)

while (rice < 1000000000, rice *= 2)

这是comma operator

的应用程序

这里的意思是:

  • 评估左侧部分rice < 1000000000,包含所有副作用。
  • rice < 1000000000没有副作用。
  • 弃掉左侧部分的评估结果(即丢弃生成的truefalse)。
  • 评估右侧部分rice *= 2,包括所有副作用。
  • 副作用是rice乘以2.
  • 将生成的rice视为boolriceint,因此0以外的每个值都被视为true。因此,rice *= 2的结果始终为true
  • 整个逗号运算符的结果是右侧部分的结果,即true

所以,问题是您的循环条件总是 true

(如果这让你感到困惑,请放心,逗号运算符确实在C ++中有用,但它们往往很少见。)

您的计划的一个可能的解决方案是:

#include <iostream>

using namespace std;

int main()
{
  double square = 2;
  double rice = 2;
  while (rice < 1000000000)
  {
    rice *= 2;
    cout << "There is " << rice << " pieces of rice that the inventor owns at square " 
         << square << endl;
    cout << "\n";
    square++;
  }
}

答案 2 :(得分:2)

您正在使用while表达式中的逗号运算符。

不要这样做。

循环中的条件表达式应始终简单易读,并且不应有副作用。正如您的问题所示,逗号运算符消除了这种简单性,增加了不必要的复杂性并且容易出错。

答案 3 :(得分:2)

这一行:

while (rice < 1000000000, rice *= 2)

这不符合你的想法。 while循环没有增量部分,因此这是一个逗号表达式,其中第一部分被评估然后被丢弃,第二部分(乘法)是实际结果。这意味着结果是rice的新值,转换为boolean,除非溢出恰好在某个时刻达到0,否则它总是为真。

你想要的是

for (; rice < 1000000000; rice *= 2)

答案 4 :(得分:2)

你正在使用复合表达式,好像它是&#34;对于&#34;

while( rice < 1000000000, rice *= 2)

真值是用逗号分隔的两个表达式中的第二个

rice *= 2

是非零值,因此是真的

无论

while ( rice < 1000000000) {

      /...
      rice *=2;
}

或使用for,其中分号符合您的预期

for ( rice = 2; rice < 10000000; rice *= 2 ) {

答案 5 :(得分:0)

您可以使用for循环来计算所需的正方形数。

T2

答案 6 :(得分:0)

我认为这是一个非常老的问题,但是我刚开始读这本书,这是我的解决方案:

#include "../../std_lib_facilities.h"

int main() {
  int current_square = 1;
  int rice_ammount = 1;
  int user_desired_ammount = 0;

  cout<<"Enter ammount of rice you want to get the ammount of squares needed: \n";
  cin>>user_desired_ammount;

  while(rice_ammount <= user_desired_ammount) {
    rice_ammount *= 2;
    cout<<"rice_ammount: "<<rice_ammount<<"\n";
    current_square++;
  }
  cout<<"Needed squares are: "<<current_square<<"\n";

  return 0;
}

没有使用固定数字来获取限制,以便测试代码如何响应不同的输入。如果您认为这是一种不好的方法,我希望有任何人提供意见。预先感谢!