我是一个编程新手(实际上在20年的间隙后又回来了:).我正试图为一个关于E—mail的问题做一个程序,找出200万以下所有素数的总和. 我正在try 使用Eratosthenes筛算法. 我正在使用代码::块与GNU GCC编译器.

 #include <stdio.h>
 #define L 2000000
 int main()
 {
     unsigned long long int i, j, n, num[L], sum = 0;
     for (i = 0; i < L; i++)
         num[i] = i + 1;

     for (j = 2; j*j <=L; j++)
         {
             for (n = j; n*j<=L; n++)
                 {
                     num[n * j - 1] = 0;
                 }
         }
     for (i = 1; i < L; i++)
         {
             if (num[i] != 0)
                 {
                     printf("%llu\n",num[i]);
                     sum = sum + num[i];
                 }
         }
     printf("%llu\n", sum);
     return 0;
 }

该程序适用于所有低于1000000的L值,但超过100000时停止工作.我也收到了关于long long int的警告,如下所示:

***||=== Build file: Debug in 2MILLIONPRIMESUM (compiler: GNU GCC Compiler) ===|

***E:\Code Blocks Projects\2MILLIONPRIMESUM\main.c||In function 'main':|

E:\Code Blocks Projects\2MILLIONPRIMESUM\main.c|22|warning: unknown conversion type character 'l' in format [-Wformat=]|

E:\Code Blocks Projects\2MILLIONPRIMESUM\main.c|22|warning: too many arguments for format [-Wformat-extra-args]|******

当我try 使用"Long Double"等时,我得到了类似的警告.这是编译器的问题吗,它不能处理Long Long和Long Double?

上述代码在gdb在线编译器上运行时没有任何警告(仅限于L&lt;=1000000). 请大家就上述问题给我提意见. 提前谢谢你了.

推荐答案

正如 comments 中指出的,2000000 * sizeof(long long)的数组太大,堆栈无法容纳;人们高度相信这是问题的根本原因.

也就是说,当我们添加动态内存分配num时,代码运行得很好,如下面的malloc()行所示. 我们还添加了代码以确保内存分配是成功的. 如果没有,则会有printf()警告用户,然后程序无害地退出.

这段代码在发布之前由我编译并运行/判断.

编辑:我刚才又做了一个测试,用sum作为类型double——最终答案仍然是一样的:142913828922. 这倾向于支持代码按照设计和需求工作的概念.

#include <stdio.h>
#include <stdlib.h>

#define L 2000000

int main()
{
    unsigned long long int i, j, n, sum = 0;
    unsigned long long int *num = malloc( L * sizeof(unsigned long long int));

    if(!num)
    {
        printf("malloc() failed!\n");
        return 0;
    }

    for (i = 0; i < L; i++)
        num[i] = i + 1;

    for (j = 2; j*j <=L; j++)
    {
        for (n = j; n*j<=L; n++)
        {
            num[n * j - 1] = 0;
        }
    }
    for (i = 1; i < L; i++)
    {
        if (num[i] != 0)
        {
            printf("%llu\n",num[i]);
            sum = sum + num[i];
        }
    }
    printf("%llu\n", sum);

    /* As you malloc(), so shall you free()! (thank you Fe2O3): */
    free(num);
    return 0;
}

输出:

    ...
    ...
    1999733
    1999771
    1999799
    1999817
    1999819
    1999853
    1999859
    1999867
    1999871
    1999889
    1999891
    1999957
    1999969
    1999979
    1999993
    142913828922

第二个版本可能会让你感兴趣:根据 comments 中与Fe203的讨论,它揭示了num数组需要not占据一个long long数据类型;num数组的范围将整齐地适合一个32位int.

此外,经过考虑,人们认识到,这种改变需要节省大量空间. 以至于perhaps the adapted 100 array may now fit on the stack!

这个概念似乎是根据可运行代码here诞生的.

显然,代码中没有任何malloc()的提示,但我们得到了符合功能的Output:

#include <stdio.h>
#include <stdlib.h>

#define L 2000000

int main()
{
    unsigned long long int sum = 0;
    unsigned int i, j, n, num[L]; 

    for (i = 0; i < L; i++)
        num[i] = i + 1;

    for (j = 2; j*j <=L; j++)
    {
        for (n = j; n*j<=L; n++)
        {
            num[n * j - 1] = 0;
        }
    }
    for (i = 1; i < L; i++)
    {
        if (num[i] != 0)
        {
            if(i > L-200) /* just print last XX of array*/
                printf("%llu\n",num[i]);
            sum = sum + num[i];
        }
    }
    printf("%llu\n", sum);
    printf("sizeof(int): %u\nsizeof(num): %u \n", sizeof(int), sizeof(num));

    return 0;
}

输出:


    1999817
    1999819
    1999853
    1999859
    1999867
    1999871
    1999889
    1999891
    1999957
    1999969
    1999979
    1999993
    142913828922
    sizeof(int): 4
    sizeof(num): 8000000 

C++相关问答推荐

获取二维数组的最大元素

getchar读css + z还是返回css?

在#include中使用C宏变量

DPDK-DumpCap不捕获端口上的传入数据包

编译的时候g++通常会比GCC慢很多吗?

fwrite无法写入满(非常大)缓冲区

为静态库做准备中的奇怪行为

如何将常量char*复制到char数组

在为hashmap创建加载器时,我的存储桶指向它自己

为什么memcpy进入缓冲区和指向缓冲区的指针工作相同?

从uint8_t*转换为char*可接受

在C++中父进程和子进程中的TAILQ队列同步问题

变量的作用域是否在C中的循环未定义行为或实现定义行为的参数中初始化?

Tic-tac-toe:从文件加载存储

C语言中MPI发送接收字符串时出现的分段错误

如何使用空元素块声明指针数组

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

STM32:代码的执行似乎取决于它在闪存中的位置

C 程序不显示任何输出,但它接受 CS50 Lab1 的输入问题

将十六进制值或十进制值分配给 uint16_t 有什么区别?