0

エラトステネスのふるいを実装する素数ジェネレーターを作成しようとしています。ただし、出力にはいくつかの合成数 (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;
}

これが出力です....

    
audit@udit-Dabba ~/Desktop/letusc/ch8 $ gcc -o Dd Dd.c -Wall
audit@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のときに停止することはありますか?

audit@udit-Dabba ~/Desktop/letusc/ch8 $ gdb ./Dd
[GDB プリアンブル省略]
(gdb) b メイン
0x100000e63 のブレークポイント 1: ファイル Dd.c、12 行目。
(gdb) r
プログラムの開始: /home/udit/Desktop/letusc/ch8/Dd
共有ライブラリの読み取りシンボル +. 終わり

Dd.c:12 のブレークポイント 1、メイン ()
12 for(i=0;i<=99;i++)
(gdb) ウォッチン
ハードウェア ウォッチポイント 2: n
(gdb)c
つづく。
ハードウェア ウォッチポイント 2: n

古い値 = 0
新しい値 = 2
main () at Dd.c:21
21 while( (n * k) < 99) {
(gdb)c
つづく。
ハードウェア ウォッチポイント 2: n

古い値 = 2
新しい値 = 3
main () at Dd.c:21
21 while( (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 を超える可能性があり、これにより任意のメモリが上書きされます (または、厳密に言えば、動作は undefinedです)。より安全に:

#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 デバッガーのチュートリアル」で Web 検索を行ってください。何百回もヒットします。次に、座って、C、C++、またはその他の多数のコンピューター言語を学習し続ける場合に何百時間も費やす強力なツールを学習して楽しんでください。(私は「楽しい」部分に真剣に取り組んでいます。楽しいと思わない場合は、CS をドロップしてください!)

「ddd debugger」も検索してください。これは gdb への無料の OSS グラフィカル フロントエンドです。とてもいいですね。

-k

于 2011-08-19T22:22:51.423 に答える
0

外側のループ内から読み取るのと同じ配列に、結果を格納しています (非素数をゼロとしてマークします)。

数値 4 は (正しく) 非素数としてマークされますが、これには、メイン ループを終了するという望ましくない副作用があります (a[j] ==0 のため)。

したがって、n=2 と n=3 のみを処理します。

于 2011-08-19T21:59:06.287 に答える
0

ヒント; 5 と 25 に何が起こったかを見てください。

Google が gdb の使い方を教えてくれます - 難しいことではありません

a[j + n * k] = 0;

私はあなたが意味すると思います

a[n * k] = 0;
于 2011-08-19T21:53:44.763 に答える
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 に答える