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 和其他内容吗?我知道问两个问题是不合适的,我的主要问题是关于 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 回答