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

C语言递归统计二进制1的个数时出现段错误是什么原因?

问题描述

尝试编写C语言代码统计一个整数二进制表示中1的个数,代码运行时触发段错误,初步怀疑问题出在binary函数的递归逻辑,需要定位具体错误原因,同时了解段错误的常规排查方法。
原始实现代码如下:

#include <stdio.h>
#include <math.h>
static int num = 0;
void binary(int target){
    int n = 0;
    int a = 1;
    if(target != 0){
        while(target >= a ){
            n++;
            a = pow(2, n);
        }
        a = pow(2, n-1);
        num++;
        binary(target - a);
    }
}

int main() {
    
    int target = 0;
    scanf("%d", &target);
    binary(target);
    printf("%d",num);
    
    return 0;
}
段错误根本原因

本次段错误本质是无限递归导致栈空间耗尽,触发逻辑链条如下:

  1. 错误使用浮点数函数pow计算2的整数次幂:pow返回值是double类型,本身存在浮点精度误差,并不适合做整数场景的精确计算。当计算结果出现偏差时,赋值给int类型的变量a会出现截断错误。
  2. 递归分支没有覆盖负数场景:当a的计算值比真实最高位权值大时,target - a会得到负数。函数进入target为负的递归分支后,while循环判断target >= a(初始a=1)永远不成立,n保持初始值0,随后计算a = pow(2, n-1) = pow(2,-1) = 0.5,截断为int后值为0。
  3. 无限递归触发栈溢出:此时执行num++后,递归调用的参数是target - 0,也就是和当前参数完全相同的负数,递归永远无法触达target == 0的终止条件,函数栈帧持续压入调用栈,直到耗尽栈空间触发内存访问越界,最终抛出段错误。
    除此之外,当输入值较大时,pow计算结果超过int取值范围会触发整数溢出,属于未定义行为,也可能直接导致内存访问错误。
修复方案

统计二进制1的个数不需要用浮点数计算,直接用位运算实现即可,既不会有精度问题,逻辑也更简洁,参考实现如下:

#include <stdio.h>

int count_one(int target) {
    int cnt = 0;
    // 处理负数的情况:转成无符号数避免右移补符号位的问题
    unsigned int n = (unsigned int)target;
    while (n != 0) {
        cnt += n & 1; // 取最低位判断是否为1
        n = n >> 1;   // 右移一位
    }
    return cnt;
}

int main() {
    int target = 0;
    scanf("%d", &target);
    printf("%d", count_one(target));
    return 0;
}

如果追求更高效率,还可以用n = n & (n-1)的技巧,每次循环直接消掉最低位的1,循环次数等于二进制中1的个数,不需要遍历所有位。

段错误常规排查方法
  • 编译阶段打开调试选项和警告:编译时加-g -Wall -Wextra参数,编译器会直接提示类型不匹配、隐式截断等明显问题,比如本次代码中pow返回double赋值给int的问题,编译器会直接抛出警告。
  • 用gdb定位崩溃位置:程序触发段错误后,在gdb中运行程序,崩溃时输入bt命令打印调用栈,可以直接看到崩溃时的代码行、递归层级、参数值,很容易定位到无限递归、空指针访问等问题。
  • 递归逻辑优先校验终止条件:写递归函数时先确认所有可能的输入分支都能走到终止条件,避免出现参数不变、无法收敛的递归分支。
  • 避免跨类型滥用函数:浮点数函数天生存在精度损失,不要用来处理需要精确结果的整数逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:57:22