逻辑出了什么问题?

时间:2011-08-19 21:49:26

标签: c primes sieve-of-eratosthenes number-theory

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

6 个答案:

答案 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)

提示;看看发生在5和25的事情

谷歌将告诉你如何使用gdb - 这不是很难

a[j + n * k] = 0;

我认为你的意思是

a[n * k] = 0;

答案 4 :(得分:0)

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

数字4被(正确地)标记为非素数,但这会产生终止主循环的不必要的副作用(因为[j] == 0)。

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

答案 5 :(得分:0)

问题是循环结束太快了。如果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++;
        }
}