0

我对 C 中的 for 循环有疑问。该程序的目的是找到已知数量 k 的素数。这是我的程序:

 unsigned int i, k, j;
    unsigned long int prime;

    int _tmain(int argc, _TCHAR* argv[]) {

    printf("How many prime numbers do you want to print out in order? "); scanf_s("%u", &k);
        printf("%u fist prime numbers are: ", k);
        i = 1;
        prime = 2;
        while (i <= k)
        {
                for (j = 2; j <= prime; j++)
                {
                    if (prime % j == 0)
                    {
                        if (j == prime && prime != 2)
                        {
                            printf("%lu, ", prime);
                            i++;
                        }
                        prime++;
                        j = 2;
                    }
                }
        }
        _getch();
    return 0;
    }

当我运行程序时,它会返回无限的数字序列。但如果我添加“else j++;” 像这样:

for (j = 2; j <= prime; j++)
                {
                    if (prime % j == 0)
                    {
                        if (j == prime && prime != 2)
                        {
                            printf("%lu, ", prime);
                            i++;
                        }
                        prime++;
                        j = 2;
                    }
                               else j++;
                }

然后程序将正常运行。我觉得这有点奇怪,无法解释为什么?

在此先感谢(并为我的英语不好感到抱歉)。

4

3 回答 3

0

正如我在评论中提到的,问题是由于您在 for 循环中没有“中断”导致它在检测到有效除数时返回到外部 while 循环。

由于您对变量名的不当使用使您感到困惑,这使情况更加复杂-您的原始代码似乎对“j”和“prime”是什么感到困惑。

在这里,我将您的代码重构为更简洁,并为大型素数搜索提供显着的性能提升:

#include <stdio.h>

#define FALSE (0)
#define TRUE (!(FALSE))

int main()
{
    int numPrimes = 0;
    int candidate, divisor;
    int isPrime;
    printf("How many prime numbers do you want to print out in order? ");
    scanf("%u", &numPrimes);
    printf("\n%u first prime numbers are:\n", numPrimes);

    if (numPrimes > 0) {
        printf("2, ");
        --numPrimes;
    }

    // we only need to test odd numbers.
    for (candidate = 3; numPrimes > 0; candidate += 2) {
        // N / (N/2) + 1 is always < 1, so we only have to test half the values.
        // we also only need to test odd divisors
        isPrime = TRUE;
        for (divisor = 3; divisor <= candidate / 2; ++divisor) {
            // it's not prime if testNumber divides in
            if (candidate % divisor == 0) {
                isPrime = FALSE;
                break;
            }
        }
        if (isPrime) {
            printf("%lu, ", candidate);
            --numPrimes;
        }
    }

    printf("\n");

    return 0;
}

现场演示:http: //ideone.com/yrUPBy

很高兴地告诉我

How many prime numbers do you want to print out in order? 
1000 first prime numbers are:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 
37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 
79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 
...
7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 
7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 
于 2013-10-24T05:13:31.563 回答
0

当程序打印 prime3时,变量具有以下值:

i = 1
j = 3
prime = 3

然后你增加iandprime和 set j = 2,所以它是:

i = 2
j = 2
prime = 4

现在您返回到循环的顶部,它会执行以下操作j++

i = 2
j = 3
prime = 4

由于j <= prime,循环继续。由于prime % jis not 0,它跳过 that 的主体if,并返回到循环的顶部,循环j再次递增:

i =2
j = 4
prime = 4

这一次prime % j == 0,所以它打印prime,即使它实际上不是质数。

对于 的每个值,这种情况都会持续发生prime

当您添加j++else子句时,它会j在失败的情况下增加两次。所以它从 3 到 5,并且永远不会出现在j == prime打印数字的情况下。然后j <= prime失败,因此for循环终止。

于 2013-10-24T04:57:08.693 回答
0

您的循环具有j <= prime作为结束条件,这意味着 的最后一个值j将等于prime。在那种情况下(prime % j == 0)将永远是真的。

当您添加额外的值时,j++您会跳过一半的值,j这些值会意外跳过问题。该程序仍然无法正常工作。

于 2013-10-24T04:51:37.197 回答