You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用埃拉托斯特尼筛法求前1000个质数的C语言代码报错求助

修复埃拉托斯特尼筛法的C语言实现问题

你的代码存在多个逻辑和语法问题,导致无法正常运行,以下是问题分析和修正方案:

核心问题分析

  • 数组越界:primelist[999]的有效索引是0到998,但你的循环中多次访问primelist[999],会触发未定义行为。
  • 变量重定义:内层for循环重新定义了int i,与外层循环的i冲突,导致循环逻辑完全混乱。
  • 初始化错误:将primelist[i]赋值为i(从1到999),包含了非质数的1,且primelist[0]未初始化,会引入垃圾值干扰判断。
  • 筛法逻辑错误:完全偏离了埃拉托斯特尼筛法的核心流程——应该从最小质数开始标记其所有倍数为非质数,而非当前代码中的混乱判断。
  • 死循环风险:while (primelist[i] != 0)的条件会因为内层循环的错误修改陷入死循环。
  • 目标不匹配:要获取前1000个质数,primelist[999]的容量完全不够,第1000个质数是7919,需要筛到至少这个数值范围。

修正后的代码

下面是正确实现前1000个质数的埃拉托斯特尼筛法代码:

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

#define TARGET_PRIMES 1000
// 第1000个质数是7919,筛到8000足够覆盖
#define SIEVE_LIMIT 8000

int main() {
    // 用布尔数组标记是否为质数,0和1初始设为非质数,其余默认是质数
    bool is_prime[SIEVE_LIMIT];
    for (int i = 0; i < SIEVE_LIMIT; i++) {
        is_prime[i] = (i >= 2);
    }

    // 埃拉托斯特尼筛法核心逻辑
    for (int p = 2; p * p < SIEVE_LIMIT; p++) {
        if (is_prime[p]) {
            // 从p的平方开始标记倍数,更小的倍数已被更小的质数标记过
            for (int multiple = p * p; multiple < SIEVE_LIMIT; multiple += p) {
                is_prime[multiple] = false;
            }
        }
    }

    // 收集前1000个质数
    int primelist[TARGET_PRIMES];
    int count = 0;
    for (int i = 2; i < SIEVE_LIMIT && count < TARGET_PRIMES; i++) {
        if (is_prime[i]) {
            primelist[count++] = i;
        }
    }

    // 输出结果,每20个换行方便阅读
    printf("前1000个质数:\n");
    for (int i = 0; i < TARGET_PRIMES; i++) {
        printf("%d ", primelist[i]);
        if ((i + 1) % 20 == 0) {
            printf("\n");
        }
    }

    return 0;
}

代码说明

  1. 数组标记法:使用bool数组is_prime标记每个数是否为质数,比直接存数更高效,逻辑更清晰。
  2. 筛法优化:从质数的平方开始标记倍数,避免重复标记已被更小质数处理过的数。
  3. 容量匹配:预先确定筛到8000,确保能覆盖第1000个质数7919。
  4. 结果收集:遍历标记数组,收集前1000个质数并格式化输出。

内容的提问来源于stack exchange,提问作者ZaneJuliun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:05:33