我正在尝试编写一个实现Eratosthenes筛子的素发生器。但是,它在输出中包含一些复合数字(例如25,49和5和7的其他倍数)。
这是我的代码:
/*****
* To find out prime numbers from 1 to 100 with a different procedure
* Author:Udit Gupta
* Date:20/08/2011
*/
#include<stdio.h>
int main() {
int a[100],i,j,k,n;
for(i=0;i<=99;i++)
a[i] = i+1; /*1 to 100 numbers are entered into array*/
/*Here te actual logic starts .......*/
j = 1;
while ( (a[j] != 0) && (j!=50) ) {
k = 1;
n = a[j];
while( (n * k) < 99) {
a[j+(n*k)] = 0;
k++;
}
j++;
}
/*To print output of the array*/
for (i=0;i<=99;i++) {
if ( a[i] != 0)
printf("\n%d",a[i]);
}
return 0;
}
这是输出....
udit@udit-Dabba ~/Desktop/letusc/ch8 $ gcc -o Dd Dd.c -Wall udit@udit-Dabba ~/Desktop/letusc/ch8 $ ./Dd
1 2 3 五 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49 53 55 59 61 65 67 71 73 77 79 83 85 89 91 95 97
答案 0 :(得分:1)
第一个提示:在调试器中,中断n = a[j];
行。运行几次迭代。它会在a[j]
== 5?
udit@udit-Dabba ~/Desktop/letusc/ch8 $ gdb ./Dd [GDB preamble elided] (gdb) b main Breakpoint 1 at 0x100000e63: file Dd.c, line 12. (gdb) r Starting program: /home/udit/Desktop/letusc/ch8/Dd Reading symbols for shared libraries +. done Breakpoint 1, main () at Dd.c:12 12 for(i=0;i<=99;i++) (gdb) watch n Hardware watchpoint 2: n (gdb) c Continuing. Hardware watchpoint 2: n Old value = 0 New value = 2 main () at Dd.c:21 21 while( (n * k) < 99) { (gdb) c Continuing. Hardware watchpoint 2: n Old value = 2 New value = 3 main () at Dd.c:21 21 while( (n * k) < 99) { (gdb) p j $1 = 2 (gdb)
RMS(与 RMS无关)GDB tutorial包含watchpoints部分,上面的示例会话使用该部分。
根据您的需要,提供更多提示。
答案 1 :(得分:1)
while (n * k < 99) {
a[j + n * k] = 0;
k++;
}
此代码很危险。您可能最终会使j + n * k
大于99,这将覆盖任意内存(或严格来说,行为未定义)。更安全:
#include <assert.h>
...
while (n * k < 99) {
int index = j + n * k;
assert(0 <= index && index < 100);
a[index] = 0;
k++;
}
答案 2 :(得分:1)
老实说,帮自己一个忙,并在“gdb调试器教程”上进行网络搜索。你会得到数百次点击。然后,坐下来学习一个功能强大的工具,如果你继续学习C,C ++或其他十几种计算机语言,你将花费数百和数百小时。 (我认真对待'乐趣'部分;我觉得你觉得它很有趣,放弃CS!)
也可以搜索'ddd debugger';这是一个免费的OSS图形前端到gdb - 非常好,恕我直言。
-k
答案 3 :(得分:0)
a[j + n * k] = 0;
我认为你的意思是
a[n * k] = 0;
答案 4 :(得分:0)
您将结果(将非素数标记为零)存储在与外循环中读取的相同数组中。
数字4被(正确地)标记为非素数,但这会产生终止主循环的不必要的副作用(因为[j] == 0)。
所以你只处理n = 2和n = 3.
答案 5 :(得分:0)
问题是循环结束太快了。如果a == 3
,a[j] == 0
并且循环结束。将主循环更改为:
for (j = 1; j < 50; j++)
{
k = 1;
n = a[j];
if (n != 0)
while (j + n * k <= 99)
{
a[j + n * k] = 0;
k++;
}
}