【问题标题】:To convert a 'for' loop into a 'do..while' loop将“for”循环转换为“do..while”循环
【发布时间】:2018-05-11 11:56:57
【问题描述】:

我遇到了一个程序,可以打印 1 到 n 之间的所有素数,其中“n”是用户提供的值。它使用了 for 循环。程序如下-

#include <stdio.h>

int main()
{
    int i, j, end, isPrime; // isPrime is used as flag variable

    /* Input upper limit to print prime */
    printf("Find prime numbers between 1 to : ");
    scanf("%d", &end);

    printf("All prime numbers between 1 to %d are:\n", end);

    /* Find all Prime numbers between 1 to end */
    for(i=2; i<=end; i++)
    {
        isPrime = 1; 
        for(j=2; j<=i/2; j++)
        {
            if(i%j==0)
                isPrime = 0;
        }
        if(isPrime==1)
        {
            printf("%4d", i);
        }
    }
    return 0;
}

我非常理解上面的代码。但只是为了测试我的知识,我尝试使用 do 循环编写相同的程序。结果不是很好。我通过书籍和互联网搜索找到一个程序,他们使用 do 循环计算素数直到 n。但是一个也找不到。我想知道它是否可能。为了展示我的努力,我把我制作的代码放在下面 -

#include <stdio.h>
main()
{
    int i, j, n, isPrime;
    printf("Enter n\n");
    scanf ("%d", &n);
    i = 2;

    do 
    {
        do
        {
            j = 2;
            if (i%j == 0)
                isPrime = 0;
            else
            {
                isPrime = 1;
                printf ("%d", i);
            }
            j = j+1;
        }
        while (j <= i/2);

        i = i+1;
    }
    while (i <= n);
}

【问题讨论】:

    标签: c do-loops


    【解决方案1】:

    你有一个好的开始,但犯了一些小错误导致了大问题

    j=2 在第二个do-while 循环中设置。这导致 j 在每个循环中都设置为 2,因此永远不会退出 do while 循环。

    接下来是 if/else。在 for 循环示例中,if (isPrime==1) 在 for 循环之外。您在 while 循环内部进行检查,导致事物很快被命名为主要方式。

    以下是工作代码示例

    #include <stdio.h>
    main()
    {
        int i, j, n, isPrime;
        printf("Enter n\n");
        scanf ("%d", &n);
        printf("All prime numbers between 2 to %d are:\n", n);
    
        i = 2;
        do 
        {
            isPrime = 1;
            j = 2;
    
            do
            {
                if (i%j == 0)
                    isPrime = 0;
                j = j+1;
            } while (j < i/2);
    
            if (isPrime == 1 || i == 2)
                printf ("%d\n", i);
            i = i+1;
        }
        while (i <= n);
    }
    

    【讨论】:

      【解决方案2】:

      这是您需要的代码。

      #include <stdio.h>
      main() {
        int i, j, n, isPrime;
        printf("Enter n\n");
        scanf("%d", &n);
        i = 2;
        do {
          j = 2;
          isPrime = 1;
          if (i == 2)
            printf("%d ", i);
          do {
            if (i % j == 0) {
              isPrime = 0;
              break;
            }
            j = j + 1;
          } while (j <= i / 2);
          if (isPrime)
            printf("%d ", i);
          i = i + 1;
        } while (i <= n);
      }
      

      【讨论】:

        【解决方案3】:

        一个for循环

        for (INIT; CONDITION; NEXT) {
            BODY;
        }
        

        相当于while循环

        {
            INIT;
            while (CONDITION) {
                BODY;
                NEXT;
            }
        }
        

        (除了for循环不允许在INITBODY的最外层块中声明相同的名称)。

        您在转换过程中犯了几个错误:

        1. do { BODY; } while (CONDITION); 语法总是至少执行一次BODY。原来的 for 循环可能不会。

        这对于i==2的情况很重要:在原始代码中,内部for循环会设置j=2,然后立即测试j&lt;=i/2是否为2&lt;=1或false,所以循环体获胜根本不执行。但是您的代码首先设置i=2; j=2;,然后直接进入因子测试if (i%j == 0)。这是真的,所以它错误地断定2 不是素数。

        1. 您将isPrime = 1;printf 语句从i 的外部循环移到j 的内部循环内部。这会严重改变程序的行为。

        考虑i==15 时会发生什么:我们从j=2 开始,发现i%j != 0 因为2 不是15 的一个因素。所以它设置isPrime = 1; 并打印15。内部循环继续,设置j=3。这次i%j == 0 因为315 的一个因子,所以它设置isPrime = 0; 并且什么也不打印。内部循环再次使用j=4。现在它回到i%j != 0,所以它设置isPrime = 1;并再次打印15。这一直持续到j=7,总共打印了四次15(当j 是2、4、6 和7 时)。

        我会让你看看你现在是否可以使用 while 循环来更正代码。

        【讨论】:

          【解决方案4】:

          试试这个代码:

          #include <stdio.h>
          main(){
          int i, j, n, isPrime;
          printf("Enter n\n");
          scanf ("%d", &n);
          i = 2;
          do 
          {
              isPrime = 1;
          
              j = 2;
          
              do
              { 
                  if (i%j == 0 && j <= i/2)
                      isPrime = 0;
                  j = j+1;
              }
              while (j <= i/2);
          
              if(isPrime == 1) printf ("%d\n", i);
          
              i = i+1;
          }
          while (i <= n);
          }
          

          for 循环转换为do-while 循环有困难。

          例如,您在代码中遇到的问题:

          • 在第二个do 循环开始时,您一遍又一遍地将j 设置为2。这意味着您陷入了无限循环,因为在循环开始时,j 的值将被重置。
          • isPrime 应该在 first do-while 循环的开头设置为 1。这样,如果i在任何点都可以被j 整除,则标志设置为0,这意味着i 不是素数。您设置它的方式的问题是,如果j 的最后一个值不划分为i,则isPrime 设置为1,即使j 的先前值划分为它。

          【讨论】:

          • 2 也是质数。
          • 啊,忘了那一点...我有时对不同类型的循环有点困惑
          猜你喜欢
          • 2015-02-16
          • 1970-01-01
          • 2018-11-21
          • 1970-01-01
          • 1970-01-01
          • 2018-02-22
          • 2017-04-26
          • 2018-08-19
          • 1970-01-01
          相关资源
          最近更新 更多