【问题标题】:Why is my loop not going infinite为什么我的循环不是无限的
【发布时间】:2013-07-17 06:38:46
【问题描述】:
#include <stdio.h>
#include <cs50.h>

int main(void)
{

    int n;
    printf("Please give me an integer greater than zero!\n");
    n=GetInt();

    if(n<0)
    {
    printf("You are giving me a bad value!\n");
    return 1;
    }


    for(int i=n-1;i<n;n--)
    printf("%d\n",n);
    return 0;
}

如果用户输入n 的数字,我想知道为什么循环不会无穷大。假设用户为n 输入了 40; i 不会一直是 n-1,所以 39 和 n 是 40,然后 i 变成 38,而 n 变成 39 等等 - 那不会造成无限循环吗?

【问题讨论】:

  • 为什么“当n变成39时我变成38”?
  • i 仅在循环的第一次迭代中小于 n。之后n 递减,现在等于i
  • 鳄鱼猎人的风格...“这不是无限循环。那是无限循环。”试想一下,我刚刚在第二句之前拔出了while(1)
  • 您似乎认为i=n-1 在每次迭代中都会发生。但它只发生在第一次。

标签: c cs50


【解决方案1】:

for(int i=n-1;i&lt;n;n--)

让我们为n = 40 画一个(非常短的)表格:

  i  |  n
-----+-----
 39  | 40    i < n ? true
 39  | 39    i < n ? false

因此,我们将在第 1st 次迭代后退出循环。

澄清

我猜你很困惑,因为你认为 i 在每次迭代中都会更新,但这就是重点 - 它没有,它的值是固定的,只有 n 正在改变.

【讨论】:

  • 这是不正确的。只发生一次迭代 - 请参阅我的分析器或 Floris 的答案。
  • 我就是这么说的:(
  • 您目前的回答是“我们将在第二次迭代后退出循环”,但实际上我们将在第一次迭代后退出循环。
【解决方案2】:

这个循环只运行一次。考虑:

 for(int i=n-1;i<n;n--)
  • 使用n == 40,在第一次迭代中,i = 39
  • 条件 i &lt; n 为真 (39 &lt; 40 == true),所以我们第一次进入循环。
  • 在第一个循环结束时,n 递减为 39
  • 条件 i &lt; n 为假 (39 &lt; 39 == false),因此我们不会第二次通过循环。

现在,如果我们让n 增加而不是减少会发生什么?这会永远运行吗?

  for(int i=n-1;i<n;n++)

答案是“可能,但可能不是”:

  • 最终,n 将达到可以存储在整数中的最大值 INT_MAX(在 limits.h 中定义,在我的系统上为 2,147,483,647)。
  • 制作大于INT_MAX 的整数会导致integer overflow
  • 有符号整数的整数溢出结果是undefined,这意味着结果可以是任何值(实际上,您的程序可能会崩溃)。

然而,在大多数系统上,该值可能会环绕到 INT_MIN 或 -2,147,483,648。

  • 如果发生这种情况,i &lt; n 将为 false,并且您的循环将终止。

但是,由于有符号整数上的整数溢出是undefined behaviour,因此您不能确定是否会发生这种情况。最好编写程序来避免这种情况。


如果您真的希望它永远运行 - 只需编写:

while(1) { ... }

for(;;) { ... }

这两个循环的优点是它们是编写无限循环的常用方法,因此易于其他程序员阅读。

【讨论】:

    【解决方案3】:

    原因是i从不递减,所以只循环1次:

     i=39 n=40
     i=39 n=39  -> stop
    

    为了减少i,你应该写:

     for(int i = n-1;i<n;n--,i--)
    

    【讨论】:

      【解决方案4】:

      i 只在循环开始时设置一次。例如,如果用户输入 10,那么在第一次迭代中 i 为 9。到第二次迭代时,n 减 1,i 仍然是 9。

      【讨论】:

        【解决方案5】:

        n 会在某些时候下溢,因为 int 是 signed 并且具有 -2147483648 到 2147483647 的值范围,例如 (x86)。 有时 n 会比 i 更积极。

        编辑: 循环最多有 1 次迭代。

        编辑 2: 例如,如果 n 的值为 -2147483648,则循环将没有迭代,因为 -2147483648 - 1 将使该值为正(两个补码整数算术)。但这永远不可能,因为前提条件是 n 可能不是负数。

        【讨论】:

        • 仔细观察循环——它只在退出条件i&lt;n返回false之前运行一次?
        • 查看 Maroun Maroun 或 trippino 的答案,详细了解为什么循环运行时间不够长导致下溢
        • 答错了,这个循环只执行了一次!
        • @bkausbk : 在开始时 n 有一个正值然后 underflow 是不可能的
        • 好吧,你是对的,如果输入值大于零,这种情况永远不会发生。
        【解决方案6】:

        您的for 循环:

        for(int i=n-1;i<n;n--) {
            printf("%d\n",n);
        }
        

        转换为以下while 循环:

        {
            int i = n - 1;
            while (i < n) {
                printf(%d\n", n);
                n--;
            }
        }
        

        for 语句的第一个子句执行初始化。它不会在每次迭代中重复,而只会重复一次。因此,i 永远不会改变值,因此循环在单次迭代后结束。

        【讨论】:

        • 我喜欢这个与 while 循环的比较。
        【解决方案7】:

        发生这种情况是因为您正在递减 n。在第二次迭代中i &lt; n 为假,您正在退出循环。

        【讨论】:

          【解决方案8】:

          会发生什么:

          //Example n = 100
          for (int i = 100 - 1; 99 < 100; 100--)
          //We now have 99 < 99 on the next loop
          //After that you will have 99 < 98 etc.. it will only run once
          

          制作你想要使用的循环:

          for(int i = n-1; i > n ; n--)
          

          要进行无限循环,请使用:

          for(;;) //or while(true)
          

          【讨论】:

          • 那还不是无限的。
          【解决方案9】:

          你的条件在 for 循环中是错误的..在你的循环中我没有改变只有 n 正在改变 试试这个

             for(i=n-1;i<n;i--)
             {
             printf("%d\n",i);
             }
          

          【讨论】:

            【解决方案10】:

            你写的完美循环...... for(int i=n-1;i

            #include<stdio.h>
            #include<conio.h>
            int main()
            {
                int i;
                for(i=0;;)
                {
                    printf("%d",i);
                }
                return 0;
            }
            

            或者你可以做任何其他事情...... 放入无限简单地制作;;在循环中的其他两个条件中。

            【讨论】:

              猜你喜欢
              • 2020-02-20
              • 2012-11-12
              • 1970-01-01
              • 1970-01-01
              • 2023-03-14
              • 1970-01-01
              • 2012-11-06
              • 2023-04-03
              相关资源
              最近更新 更多