递归实现前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
相关产品推荐
相关产品推荐

