for loop C的工作很奇怪?

时间:2013-10-24 04:34:24

标签: c for-loop

我在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++;
                }

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

提前致谢(对不起我的英语不好)。

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

当程序打印素数3时,变量具有以下值:

i = 1
j = 3
prime = 3

然后你增加iprime,并设置j = 2,所以它是:

i = 2
j = 2
prime = 4

现在返回循环的顶部,j++

i = 2
j = 3
prime = 4

j <= prime开始,循环继续。由于prime % j不是0,它会跳过if的正文,然后返回到循环的顶部,再次递增j

i =2
j = 4
prime = 4

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

prime的每个值都会发生这种情况。

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

答案 2 :(得分:0)

正如我在评论中提到的,问题是由于你在for循环中没有“break”导致它在你检测到有效除数时返回到外部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,