【问题标题】:goto statement leading to an infinite loopgoto 语句导致无限循环
【发布时间】:2020-12-31 03:11:24
【问题描述】:

我们进行了各种各样的测验,并且有以下问题,我们必须在哪里找到错误,或者如果没有,则给出给定代码的输出:

#include <stdio.h>

int main(void) {
  int n = 012;

  b: printf("%d\n",n--);

  if(n!=0){
    n--;
    goto b;
  }
  
  return 0;
}

理论上我看不出这有什么问题,但这会导致变量低于 0 的无限循环。谁能帮我解决这个问题?

【问题讨论】:

  • 你学到了什么调试?您是否打算在两个地方减少 n
  • 用纸和铅笔逐一检查代码并跟踪n 的值。只需一分钟。你会明白为什么测试n != 0 不会停止循环。请注意,文字 012 是一个 八进制 值。
  • iteration 将为索引打印 n, 10,8,6,4,2,0 ,在 printf 中打印之后,我们将 n 减 1。当 n 到达 if 语句时,它将是 9, 7,5,3,1,-1。并且终止条件 n==0 永远不会命中。如果打算打印 "10,8,6,4,2,0 " ,请将终止条件从 " if(n!=0){ " 更改为 "if(n>0){"。
  • 使用函数的早期返回,if 语句。有很多技术不需要goto,我认为这些技术更容易确保代码正确。一个原因(恕我直言,一个非常好的原因)是回答“你是如何获得 goto 标签的?”这个问题在编写代码时可能很容易回答,但经过长时间的维护后,它变得更难检查。跨度>

标签: c goto


【解决方案1】:
#include <stdio.h>

int main(void) {
  int n = 012;

  b: printf("%d\n",n);

  if(n!=0){
    n--;
    goto b;
  }
  
  return 0;
}

这会奏效。您发布的版本不起作用,因为它永远不会变为 0。它在 if 语句中减去一次,在 printf 中减去一次。

【讨论】:

    【解决方案2】:

    你应该只有一个 n-- 语句。否则即使它达到0,当它得到第一个n时,它会再递减一次,变成-1。 (所以它永远不会匹配 0)。

    因此,请将您的代码更改为

    #include <stdio.h>
    
    int main(void) {
      int n = 012;
    
      b: printf("%d\n",n--);
    
      if(n!=0){
       goto b;
      }
      
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      条件if (n != 0) 总是得到满足。

      在每次迭代中,n 的数量会减少 2。

      所以当 n = 2 时,它会在printf("%d\n",n--) 之后递减一次

      那么条件if (n != 0)为真,如n = 1

      在条件块内n再次递减,n = 0

      所以下一次在达到条件if (n != 0)之前,n等于-1,

      这会导致无限循环。

      【讨论】:

      • 由于 n 递减两次,当 n 开始为偶数时,if 条件只看到奇数。如果 n 以奇数开始,则 if 条件只看到偶数并且迭代结束。
      【解决方案4】:

      在 C 中 012 是八进制基数,十进制等于 10。

      这段代码:

      #include <stdio.h>
      
      int main(void) {
        int n = 012;
      
        b: printf("%d\n",n--);
      
        if(n!=0){
          n--;
          goto b;
        }
        
        return 0;
      }
      

      这样做:

      print n (10)
      subtract 1 of n (n = 10 - 1 = 9)
      check if n != 0 (9 != 0 -> true)
      subtract 1 of n (n = 9 - 1 = 8)
      jump to b
      
      print n (8)
      subtract 1 of n (n = 8 - 1 = 7)
      check if n != 0 (7 != 0 -> true)
      subtract 1 of n (n = 7 - 1 = 6)
      jump to b
      
      print n (6)
      subtract 1 of n (n = 6 - 1 = 5)
      check if n != 0 (5 != 0 -> true)
      subtract 1 of n (n = 5 - 1 = 4)
      jump to b
      
      print n (4)
      subtract 1 of n (n = 4 - 1 = 3)
      check if n != 0 (3 != 0 -> true)
      subtract 1 of n (n = 3 - 1 = 2)
      jump to b
      
      print n (2)
      subtract 1 of n (n = 2 - 1 = 1)
      check if n != 0 (1 != 0 -> true)
      subtract 1 of n (n = 1 - 1 = 0)
      jump to b
      
      print n (0)
      subtract 1 of n (n = 0 - 1 = -1)
      check if n != 0 (-1 != 0 -> true)
      subtract 1 of n (n = -1 - 1 = -2)
      jump to b
      
      print n (-2)
      ...
      ...
      ... goes on infinitely
      

      请注意,当程序检查 n != 0 时,n 永远不会等于 0,因为在此评估中,n 始终是奇数,因为每次都会进行两次减 1。

      【讨论】:

        【解决方案5】:

        b: printf("%d\n",n--); 更改为b: printf("%d\n",n);

        改变

          if(n!=0){
            n--;
            goto b;
        

          if(n!=0){
            n;
            goto b;
        

        因为n-- 等于n = n - 1

        你的程序:

        #include <stdio.h>
        
        int main(void) {
          int n = 012;
        
          b: printf("%d\n",n--); // n = n - 1
        
          if(n!=0){
            n--; // n = n - 1
            goto b;
          }
          
          return 0;
        }
        

        【讨论】:

          【解决方案6】:

          对于输出 [10, 8, 6, 4,2, 0]

              #include <stdio.h>
          
              int main(void) {
                int n = 012;
          
                b: printf("%d\n",n--);
          
                if(n>0){
                  n--;
                  goto b;
                }
          
                return 0;
              }
          

          对于 [10,9,8,7,6,5,4,3,2,1]

              #include <stdio.h>
          
              int main(void) {
                int n = 012;
          
                b: printf("%d\n",n--);
          
                if(n>0){
                  //n--;
                  goto b;
                }
          
                return 0;
              }
          

          【讨论】:

            猜你喜欢
            • 2015-01-11
            • 2013-08-26
            • 2023-01-25
            • 2019-06-18
            • 1970-01-01
            • 2020-08-27
            • 2021-05-07
            • 2012-08-24
            相关资源
            最近更新 更多