我在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++;
}
然后程序将正常运行。我觉得这有点奇怪,无法解释为什么?
提前致谢(对不起我的英语不好)。
答案 0 :(得分:0)
您的循环以j <= prime
作为结束条件,这意味着j
的最后一个值将等于prime
。在这种情况下,(prime % j == 0)
将永远为真。
当您添加额外的j++
时,您将跳过j
的一半意外跳过问题的值。该程序仍然无法正常工作。
答案 1 :(得分:0)
当程序打印素数3
时,变量具有以下值:
i = 1
j = 3
prime = 3
然后你增加i
和prime
,并设置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;
}
很高兴地告诉我
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,