0

我正在尝试编写一个实现 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 5 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

4

6 回答 6

1

第一个提示:在调试器中,中断就n = a[j];行。运行几次迭代。a[j]== 5时它会停止吗?

udit@udit-Dabba ~/Desktop/letusc/ch8 $ gdb ./Dd
[省略 GDB 序言]
(gdb) b 主要
0x100000e63 处的断点 1:文件 Dd.c,第 12 行。
(gdb) r
启动程序:/home/udit/Desktop/letusc/ch8/Dd
共享库的读取符号 +。完毕

断点 1,主 () 在 Dd.c:12
12 for(i=0;i<=99;i++)
(gdb) 观看 n
硬件观察点 2:n
(gdb) c
继续。
硬件观察点 2:n

旧值 = 0
新值 = 2
主 () 在 Dd.c:21
21同时((n * k)<99){
(gdb) c
继续。
硬件观察点 2:n

旧值 = 2
新值 = 3
主 () 在 Dd.c:21
21同时((n * k)<99){
(gdb) pj
$1 = 2
(gdb)

RMS(与那个 RMS无关)GDB 教程包括一个关于watchpoints的部分,上面的示例会话使用了该部分。

更多提示可以根据您的需要进行。

于 2011-08-19T22:01:48.493 回答
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++;
}
于 2011-08-19T22:09:39.187 回答
1

老实说,帮自己一个忙,在“gdb 调试器教程”上进行网络搜索。您将获得数百次点击。然后,坐下来享受一些乐趣,学习一个强大的工具,如果你继续学习 C、C++ 或其他十几种计算机语言,你将花费成百上千个小时来使用它。(我对“有趣”的部分很认真;我觉得它不好玩,放弃 CS!)

还要搜索“ddd 调试器”;这是 gdb 的免费 OSS 图形前端——非常好,恕我直言。

-k

于 2011-08-19T22:22:51.423 回答
0

暗示 ; 看看 5 和 25 发生了什么

google 会告诉你如何使用 gdb - 并不难

a[j + n * k] = 0;

我想你的意思是

a[n * k] = 0;
于 2011-08-19T21:53:44.763 回答
0

您将结果(将非素数标记为零)存储在与从外部循环中读取的相同数组中。

数字 4 被(正确地)标记为非素数,但这具有终止主循环的不良副作用(因为 a[j] ==0)。

所以你只处理 n=2 和 n=3。

于 2011-08-19T21:59:06.287 回答
0

问题是循环结束得太快了。if a == 3a[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++;
        }
}
于 2011-08-19T22:21:15.317 回答