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

递归实现前N个素数打印的C代码错误排查求助

递归素数代码输出异常的原因及修复方案

你的代码输出异常的核心问题出在isPrime函数的静态变量i设计上,以下是具体分析和修复方案:

错误原因

isPrime中声明的static int i = 2;只会在第一次调用函数时初始化一次,后续所有调用都会沿用之前的i值,不会重置为2:

  • 比如判断完数字8后,i的值已经递增到4;接下来判断9时,i直接从4开始,而9/2=4.5,此时i > n/2的条件成立,函数直接返回true,错误地将9判定为素数。
  • 同理,判断15时,之前的i值已经大于7(15/2=7.5),同样直接返回true,导致15被误判。

修复方案

方案1:移除静态变量,改用参数传递实现递归判断(推荐)

将素数判断的除数i作为参数传递,每次判断新数字时从2开始,避免静态变量的残留值影响结果:

bool isPrime(int n, int i) {
    // 边界情况:小于等于1的数不是素数
    if (n <= 1)
        return false;
    // 递归终止条件:除数超过n的一半,说明n是素数
    if (i > n / 2)
        return true;
    // 能被整除则不是素数
    if (n % i == 0)
        return false;
    // 递归检查下一个除数
    return isPrime(n, i + 1);
}

同时修改primeNumbers中的调用逻辑,传入初始除数2:

if (isPrime(i, 2))

方案2:重置静态变量(不推荐)

如果坚持使用静态变量,需要在每次判断新数字时重置i的值,但这种方式会引入线程安全问题,且多次调用isPrime时容易出错。示例如下(仅作演示):

bool isPrime(int n) {
    if (n <= 1)
        return false;
    
    static int i = 2;
    // 每次判断新数字时重置i为2
    static int prev_n = -1;
    if (n != prev_n) {
        i = 2;
        prev_n = n;
    }
    
    if (i > n / 2)
        return true;
    if (n % i == 0)
        return false;
    
    i++;
    return isPrime(n);
}

修复后的完整代码

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

bool isPrime(int n, int i) {
    if (n <= 1)
        return false;
    if (i > n / 2)
        return true;
    if (n % i == 0)
        return false;
    return isPrime(n, i + 1);
}

void primeNumbers(int n) {
    if (n == 0)
        return;

    static int i = 2;

    if (isPrime(i, 2)) {
        printf("%d ", i);
        i++;
        primeNumbers(n - 1);
    } else {
        i++;
        primeNumbers(n);
    }
}

int main() {
    primeNumbers(10);
    return 0;
}

运行上述代码,输入n=10时会输出正确的前10个素数:2 3 5 7 11 13 17 19 23 29

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:52:50