1

Python で行ったことのいくつかを C に翻訳することで C を学んでいます。ここに来る前にできる限りオンラインで調べてみましたが、探しているものに対する答えを見つけるのは非常に難しいようです。

以下は、数値の素数性に対するミラー・ラビン検定の (これまでの) 私の翻訳です。

#include <stdio.h>
#include <math.h>

_Bool prime(long long n);

int main() {
    int i = 6;
    for (i; i < 9; i++) {
        if (prime(i)) {
            printf("%i\n", prime(i));
        }
    }
}

_Bool prime(long long n) {
    int s = 0;
    int r = 0;
    int a_index = 0;
    // printf("the value of a_index when initialised is: %d\n", a_index);
    // printf("the value of s when initialised is: %d\n", s);
    int *a_list;
    _Bool is_prime = 1;
    _Bool composite_part_a = 1;
    _Bool composite_part_b = 1;
    long long d = n - 1;
    while (d % 2 == 0) {
        s++;
        d = d / 2;
    }

    if (4759123141 <= n && n < 2152302898747) {
        // malloc
        a_list[0] = 2;
        a_list[1] = 3;
        a_list[2] = 5;
        a_list[3] = 7;
        a_list[4] = 11;
    }
    else if (9080191 <= n && n < 4759123141) {
        // malloc
        a_list[0] = 2;
        a_list[1] = 7;
        a_list[2] = 61;
    }
    else if (1373653 <= n && n < 9080191) {
        // malloc
        a_list[0] = 31;
        a_list[1] = 73;
    }           
    else if (4 <= n && n < 1373653) {
        a_list = (int *) malloc(sizeof(int) * 2);
        a_list[0] = 2;
        a_list[1] = 3;
        printf("the value of a_list[0] upon its first assignment is: %d\n", a_list[0]);
        // printf("the first element of a_list is: %d\n", a_list[0]);
        // printf("the second element of a_list is: %d\n", a_list[1]);
    }
    else if (n == 3 | n == 2) {
        return 1;
    }
    else if (n % 2 == 0 | n == 1) {
        return 0;
    }

    printf("the value of a_list[0] over here is: %d\n", a_list[0]);
    // printf("%d\n", a_list[1]);  
    for (a_index; a_index < sizeof(a_list) / sizeof(int); a_index++) {
        printf("test");
        if ((long long)pow(a_index[a_list], d) % n != 1) {
            composite_part_a = 1;
        }
        else {
            composite_part_a = 0;
        }


        // printf("the value of r is: %d\n", r);
        // printf("the value of s is: %d\n", s);
        for (r; r < s; r++) {
            printf("%lld\n", (int)pow(a_list[a_index], exp2(r) * d) % n);
            if ((long long)pow(a_index[a_list], exp2(r) * d) % n != -1) {
                composite_part_b = 1;
            }
            else {
                composite_part_b = 0;
                break;
            }
            }

        if (composite_part_a && composite_part_b) {
            return 0;
        }
        }

    return is_prime;
    }

C を学ぶ上での問題は、K&R について聞いたこと以外に、純粋な初心者向けの優れた文献があまりないことですが、それはメールにあり、今は手に入れることができません。プログラムは次のエラーを返します。

3.c: In function ‘prime’:
3.c:52:26: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
/tmp/ccGQnk9T.o: In function `prime':
3.c:(.text+0x272): undefined reference to `pow'
3.c:(.text+0x2b9): undefined reference to `exp2'
3.c:(.text+0x2db): undefined reference to `pow'
3.c:(.text+0x30b): undefined reference to `exp2'
3.c:(.text+0x32d): undefined reference to `pow'
collect2: ld returned 1 exit status

まず、pow などを紹介するために含めたのではないでしょうか。2 つの質問をするのは適切ではないことはわかっています。私の主な質問は pow と exp2 に関するものですが、malloc についても提案がある場合は、遠慮なく含めてください。

4

4 に答える 4

5

数学ライブラリもリンクする必要があります。デフォルトでは含まれていません。

次のコマンドのようなもの:

$ gcc 3.c -lm

-lm引数に注意してください... これは、リンカーにライブラリ (-lパーツ) とライブラリの名前(パーツ) を追加するように指示しますm

于 2012-10-10T12:33:56.860 に答える
3

数学関数は の一部ですlibm。でコンパイルするときにそれらをリンクします-lm

于 2012-10-10T12:33:23.167 に答える
1

3.c:52:26: 警告: 組み込み関数 'malloc' の互換性のない暗黙の宣言 [デフォルトで有効]

インクルードの欠落が原因で、malloc() は stdlib.h で定義されているため、それを含める必要があります。

3.c:(.text+0x272): `pow' (およびその他) への未定義の参照

libm へのリンクが見つからないことが原因です。math.h のほとんどの (すべてではないにしても) メソッドは、常にリンクされる標準の libc ではなく、代わりに libm にあります。

リンク方法はコンパイラによって異なりますが、gcc (および他の多くの UNIX コンパイラ) の場合:

gcc 3.c -o 3 -lm

「-lm」はgccにlibmをリンクするように指示します。

于 2012-10-10T12:36:47.123 に答える
0

<stdlib.h>malloc と freeを含める必要があります。

数学を機能させるには、リンクする必要が あります。ライブラリ フラグはgcc 3.c -lm どこ-lにあり、m は数学ライブラリを使用するように指示します。

また、プライムの定義をメインの上に移動する必要があります。物事は順番に宣言する必要があります。

ここから始めたばかりなので、コンパイラに役立つその他のフラグがいくつかあります

-gこれにより、valgrind または gdb を使用する際のデバッグが改善されます。

-oコンパイルされたファイル名を定義できます。例:の代わりにgcc 3.c -o 3作成します./3./a.out

于 2012-10-10T12:35:59.583 に答える