while循环在C中不检查条件。

huangapple go评论65阅读模式
英文:

while loop not checking for condition in C

问题

I just started Harvard's cs50 course and I am currently having difficulties understanding why my code for Lab 1: Population Growth keeps running forever. Below is the program for determining how long it takes for a population to reach a particular size. Near the end, my while loop isn't stopping even though the condition is reached.

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    // Prompt for start size
    int i;
    do
    {
        i = get_int("Start size: ");
    }
    while (i < 9);

    // Prompt for end size
    int z;
    do
    {
        z = get_int("End size: ");
    }
    while (z < i);

    // year_count
    int n = 0;
    // Increase the year_count n for every loop until start size i reaches end size z
    while ((i < z) || (i != z))
    {
        // population after a year
        i = i + i / 3 - i / 4;
        n++;
        // the loop doesn't terminate itself, so I had to force a break
        if ((i > z) || (i == z))
        {
            break;
        }
    }

    // Print the number of years
    printf("Years: %i\n", n);
}
英文:

I just started Harvard's cs50 course and I am currently having difficulties understanding why my code for Lab 1: Population Growth keeps running forever. Below is the program for determining how long it takes for a population to reach a particular size. Near the end, my while loop isn't stopping even though the condition is reached.

#include &lt;cs50.h&gt;
#include &lt;stdio.h&gt;

int main(void)
{
    // Prompt for start size
    int i;
    do
    {
        i = get_int(&quot;Start size: &quot;);
    }
    while (i &lt; 9);

    // Prompt for end size
    int z;
    do
    {
        z = get_int(&quot;End size: &quot;);
    }
    while (z &lt; i);

    // year_count
    int n =  0;
//    Increase the year_count n for every loop until start size i reaches end size z
    while ((i &lt; z) || (i != z))
    {
//        population after a year
        i = i + i / 3 - i / 4;
        n++;
//        the loop doesnt terminate itself so i had to force break
        if ((i &gt; z) || (i == z))
        {
            break;
        }
    }

    // Print number of years
    printf(&quot;Years: %i\n&quot;, n);
}

答案1

得分: 4

With while ((i &lt; z) || (i != z)), the loop fails to terminate because i passes z. For some inputs, there is never an iteration of the loop when i is exactly z. For example, with inputs of 10 and 100, i reaches 96 in one iteration and is then 104 in the next.

When i is 104, i &lt; z is false but i != z is true. So the loop continues.

The loop test you want is i &lt; z.

You could have discovered this by printing useful information in each loop iteration, such as:

printf("i = %d.\n", i);
printf("z = %d.\n", z);
printf("i &lt; z = %d.\n", i &lt; z);
printf("i != z = %d.\n", i != z);

That would have revealed to you how the conditions for the while were being evaluated.

英文:

With while ((i &lt; z) || (i != z)), the loop fails to terminate because i passes z. For some inputs, there is never an iteration of the loop when i is exactly z. For example, with inputs of 10 and 100, i reaches 96 in one iteration and is then 104 in the next.

When i is 104, i &lt; z is false but i != z is true. So the loop continues.

The loop test you want is i &lt; z.

You could have discovered this by printing useful information in each loop iteration, such as:

printf(&quot;i = %d.\n&quot;, i);
printf(&quot;z = %d.\n&quot;, z);
printf(&quot;i &lt; z = %d.\n&quot;, i &lt; z);
printf(&quot;i != z = %d.\n&quot;, i != z);

That would have revealed to you how the conditions for the while were being evaluated.

答案2

得分: 0

代码中的while循环似乎不会停止,这是因为你使用的条件。

while ((i &lt; z) || (i != z))

如果目标人口大小z没有达到,就会检查当前人口大小i是否小于目标人口大小z。这个条件的问题在于,当i小于z时,它总是为真,因为直到两者相等之前,i永远不会等于z。这意味着即使在人口超出预期大小之后,你的循环仍然会运行。

你需要修改while循环的条件来纠正这个问题。将逻辑或(||)运算符更改为逻辑与(&&)运算符是一种方法。通过这样做,你可以确保循环仅在i小于z且不等于z时执行。

while (i &lt; z) && (i != z))

这将只在当前人口大小i小于目标人口大小z时继续循环。一旦i大于或等于z,循环将终止。

英文:

It seems like the while loop in your code is not stopping because of the condition you have used.

while ((i &lt; z) || (i != z))

If the target population size z is not met, the current population size i is checked to see if it is less than the target population size z. This condition has the drawback of always being true when i &lt; z because i will never equal z until it does. This implies that even after the population has beyond the intended size, your loop will still be in operation.

You must modify the while loop's condition in order to correct this. Changing the logical OR (||) operator to the logical AND (&amp;&amp;) operator is one approach to accomplish this. By doing this, you can make sure that the loop only executes when i is lower than z and not equal to z. Here's

while (i &lt; z) &amp;&amp; (i != z))

This will continue the loop only while the current population size i is less than the target population size z. Once i becomes greater than or equal to z, the loop will terminate.

答案3

得分: 0

The condition while ((i &lt; z) || (i != z)) may never be false if i passes the value of z without reaching it exactly. Note that (i &lt; z) || (i != z) is redundant as all cases where (i &lt; z) also match (i != z).

为了实现你的目标,即“确定人口达到特定规模需要多长时间”,测试应该简化为 while (i &lt; z),因为你应该在 i &gt;= z 时停止。循环应该简化为:

    while (i &lt; z) {
        // 一年后的人口
        i += i / 3 - i / 4;
        n++;
    }

请注意,有一些特殊情况,其中 i 可能会溢出,例如,如果 zINT_MAX (2147483647)。

以下是修改后的版本:

#include &lt;cs50.h&gt;
#include &lt;stdio.h&gt;

int main(void) {
    // 提示起始大小
    int i;
    do { i = get_int(&quot;Start size: &quot;); } while (i &lt; 9);

    // 提示结束大小
    int z;
    do { z = get_int(&quot;End size: &quot;); } while (z &lt; i);

    // 年数
    int n =  0;
    // 每次循环增加一年,直到起始大小 i 达到结束大小 z
    while (i &lt; z) {
        // 一年后的人口
        i += i / 3 - i / 4;
        n++;
    }

    // 打印年数
    printf(&quot;Years: %i\n&quot;, n);
    return 0;
}

为了避免溢出,你可以这样写:

#include &lt;limits.h&gt;

...

    while (i &lt; z) {
        // 一年后的人口
        int growth = i / 3 - i / 4;
        // 检查潜在的溢出
        if (i &gt; INT_MAX - growth) {
            i = INT_MAX;
        } else {
            i += growth;
        }
        n++;
    }
英文:

The condition while ((i &lt; z) || (i != z)) may never be false if i passes the value of z without reaching it exactly. Note that (i &lt; z) || (i != z) is redundant as all cases where (i &lt; z) also match (i != z).

To achieve your goal, Determine how long it takes for a population to reach a particular size, the test should just be while (i &lt; z) because you should stop as soon as i &gt;= z. The loop should be simplified as:

    while (i &lt; z) {
        // population after a year
        i += i / 3 - i / 4;
        n++;
    }

Note that there are some corner cases, where i may overflow as it passes z, eg: if z is INT_MAX (2147483647).

Here is a modified version:

#include &lt;cs50.h&gt;
#include &lt;stdio.h&gt;

int main(void) {
    // Prompt for start size
    int i;
    do { i = get_int(&quot;Start size: &quot;); } while (i &lt; 9);

    // Prompt for end size
    int z;
    do { z = get_int(&quot;End size: &quot;); } while (z &lt; i);

    // year_count
    int n =  0;
    // Increase the year_count n for every loop until start size i reaches end size z
    while (i &lt; z) {
        // population after a year
        i += i / 3 - i / 4;
        n++;
    }

    // Print number of years
    printf(&quot;Years: %i\n&quot;, n);
    return 0;
}

To avoid the overflow, you could write this:

#include &lt;limits.h&gt;

...

    while (i &lt; z) {
        // population after a year
        int growth = i / 3 - i / 4;
        // check for potential overflow
        if (i &gt; INT_MAX - growth) {
            i = INT_MAX;
        } else {
            i += growth;
        }
        n++;
    }

huangapple
  • 本文由 发表于 2023年4月6日 23:21:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定