我不明白这个无限循环

问题描述 投票:0回答:8

如果这看起来很容易修复,我很抱歉,但我在执行本应简单的 while 循环时遇到了一些奇怪的事情。谁能帮我解决为什么这个循环永远持续下去吗?

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

有一个古老的故事,皇帝要感谢发明者 棋局并要求发明者说出他的奖励。这 发明者要求第一个方格需要一粒米,第二个方格需要两粒米 第二个,第三个 4,依此类推,64 个中的每个加倍 这可能听起来很平常,但里面没有那么多米 帝国!编写一个程序来计算 需要多少个方格才能给发明人至少1000粒米、至少1,000,000粒米、至少1,000,000,000粒米 当然,你需要一个循环,可能还需要一个 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 上得到了同样的结果。

c++ while-loop
8个回答
4
投票
问题处于

while (rice < 1000000000, rice *= 2)

状态。如果多个语句之间用逗号分隔,则整个语句的结果等于最后一个语句的结果。所以你实际上拥有 
while (rice *= 2)
 这绝对是真的。


3
投票
while (rice < 1000000000, rice *= 2)


这是

逗号运算符的应用

这里的意思是:

    评估左侧部分,
  • rice < 1000000000
    ,以及所有副作用。
  • rice < 1000000000
    没有任何副作用。
  • 丢弃左侧部分的评估结果(即丢弃所得的true
    false
    )。
  • 评估正确的部分,
  • rice *= 2
    ,以及所有副作用。
  • 副作用是
  • rice
    乘以2。
  • 将生成的
  • rice
     视为 
    bool
    rice
     是一个 
    int
    ,因此除 0 之外的每个值都被视为 
    true
    。因此 
    rice *= 2
     的结果始终是 
    true
  • 整个逗号运算符的结果是
  • 右侧部分的结果,即true
所以,问题是你的循环条件是

always 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
投票
您在 while 表达式中使用了逗号运算符。

别这样做。

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


2
投票
这一行:

while (rice < 1000000000, rice *= 2)

这并不像你想象的那样。 while 循环没有增量部分,因此这是一个逗号表达式,其中第一部分被计算然后被丢弃,第二部分(乘法)是实际结果。这意味着结果是

rice

 的新值,转换为布尔值,除非在某个时刻发生溢出恰好达到 0,否则该值始终为 true。

你想要的是

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

2
投票
您在 while 中使用了复合表达式,就好像它是“for”

while( rice < 1000000000, rice *= 2)

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

rice *= 2

是非零值,因此为真

要么

while ( rice < 1000000000) { /... rice *=2; }

或使用 for,其中分号执行您所期望的操作

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

0
投票
您可以使用for循环来计算需要多少个正方形。

int main () { int grain = 1 ; for (int i = 2; i < 65 ; ++i) // iteration for each of the 64 squares, starting from square 2 { grain += grain ; // doubling for each of the 64 squares if (grain > 1000 && grain < 2000) // at least 1000 grains of rice { cout << "square is: " << i << " grains is: " << grain << '\n' ; } if (grain > 1000000 && grain < 2000000) // at least 1,000,000 grains { cout << "square is: " << i << " grains is: " << grain << '\n' ; } if (grain > 1000000000 && grain < 2000000000) //at least 1,000,000,000 grains { cout << "square is: " << i << " grains is: " << grain << '\n' ; } } return 0; }
    

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

#include "../../std_lib_facilities.h" int main() { int current_square = 1; int rice_amount = 1; int user_desired_amount = 0; cout<<"Enter amount of rice you want to get the number of squares needed: \n"; cin>>user_desired_amount; while(rice_amount <= user_desired_amount) { rice_amount *= 2; cout<<"rice_amount: "<<rice_amount<<"\n"; current_square++; } cout<<"Needed squares are: "<<current_square<<"\n"; return 0; }
没有使用固定数字来获得限制来测试代码如何响应不同的输入。如果您认为这是一个不好的方法,我很乐意听取任何人的意见。预先感谢!


0
投票
我使用向量来跟踪所有积累的谷物。

int squareIn{ 0 }; int currentSquareQuantity{ 0 }; unsigned int totalGrain{ 0 }; vector <unsigned int> squares; int counter{ 1000 }; for (int i = 0; i <= 32; ++i) { squares.push_back(pow(2, i)); currentSquareQuantity = squares[i]; // quantity of grain in the current square squareIn = i + 1; // square number totalGrain += currentSquareQuantity; // the sum of the grain accumulated in all the squares up to now... while (totalGrain > counter && totalGrain < counter * 2) { cout << "With all first " << squareIn << " square filled " << "you would have " << totalGrain << " granes \n\n"; cout << "so you require at least " << squareIn << " squares for a total of grain equal to " << counter << "\n\n"; cout << "------------------" << "\n\n"; if (counter > 2000000000) { return 0; } counter = counter * 1000; } }
    
© www.soinside.com 2019 - 2024. All rights reserved.