You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言实现二项式系数计算器:scanf输入校验逻辑错误排查与修正求助

C语言实现二项式系数计算器:scanf输入校验逻辑错误排查与修正求助

我最近在写一个计算二项式系数的C程序,需求是这样的:

  • scanf获取用户输入的两个整数n和k
  • 只要其中任意一个scanf的返回值不是1(也就是输入失败),就打印"Failed"并返回1退出
  • 输入正常的话,先计算Pochhammer符号nₖ(也就是n*(n-1)...(n-k+1)),再计算k的阶乘,最后用前者除以后者得到二项式系数,然后循环回到开头继续接收新的输入

我自己写了一段代码,但只要保留scanf的返回值校验部分,程序就完全不正常,把校验代码注释掉之后反而能正常计算。麻烦帮我看看我在输入校验这里犯了什么错误,该怎么修正?

我的原始代码如下:

#include <stdio.h>

unsigned long long bin_cof ( int bc_n , int bc_k ) {
    //calculate pochhammer symbol n_k
    int i = 0 ;
    unsigned long long poc = 1 ;
    for ( ; i < bc_k ; i++ ) {
        poc = poc * ( bc_n - i ) ;
    }
    //calculate factorial k!
    i = 1 ;
    unsigned long long fac = 1 ;
    for ( ; i < bc_k ; i++ ) {
        fac = fac * ( i + 1 ) ;
    }
    //calculate binomial coefficient
    return poc / fac ;
}

int main ( ) {
    printf ( "Give me an n : " ) ;
    int n ;
    scanf ( "%d" , &n ) ;
    printf ( "Give me a k : " ) ;
    int k ;
    scanf ( "%d" , &k ) ;

    if ( scanf ( "%d" , &n ) != 1 ) {
        printf ( "!!Failed!!" ) ;
        return 1 ;
    }
    if ( scanf ( "%d" , &k ) != 1 ) {
        printf ( "!!Failed!!" ) ;
        return 1 ;
    }

    printf ( "\n%dC%d = %llu\n\n" , n , k , bin_cof ( n , k ) ) ;
    main ( ) ;
    return 0 ;
}

问题分析

你的代码主要有两个核心问题:

  1. 重复调用scanf导致输入逻辑混乱
    你先执行了两次scanf获取n和k,之后又再次调用scanf来做返回值校验——这相当于要求用户输入两次n和两次k!如果用户只输入了一组n和k,第二次scanf就会读取失败,直接触发"Failed"提示,这就是为什么校验代码一保留程序就出错的原因。

  2. 递归调用main的不规范写法
    你用main()递归调用自己来实现循环输入,这不符合C语言的规范,而且多次递归会导致栈溢出,非常不安全。

另外,你的阶乘计算逻辑虽然结果正确,但写法过于绕,很容易出错,建议简化。

修正后的代码

#include <stdio.h>

unsigned long long bin_cof(int bc_n, int bc_k) {
    // 计算Pochhammer符号n_k
    unsigned long long poc = 1;
    for (int i = 0; i < bc_k; i++) {
        poc *= (bc_n - i);
    }

    // 计算k的阶乘,简化直观写法
    unsigned long long fac = 1;
    for (int i = 1; i <= bc_k; i++) {
        fac *= i;
    }

    return poc / fac;
}

int main() {
    while (1) { // 用while循环实现重复输入,替代递归main
        int n, k;
        printf("Give me an n: ");
        // 输入n的同时完成校验
        if (scanf("%d", &n) != 1) {
            printf("!!Failed!!\n");
            return 1;
        }

        printf("Give me a k: ");
        // 输入k的同时完成校验
        if (scanf("%d", &k) != 1) {
            printf("!!Failed!!\n");
            return 1;
        }

        // 计算并输出二项式系数
        printf("\n%dC%d = %llu\n\n", n, k, bin_cof(n, k));
    }
    return 0;
}

修正说明

  1. 合并输入与校验逻辑
    现在每次调用scanf后立刻判断返回值,用户只需要输入一次n和k,输入失败直接触发错误提示,逻辑清晰且完全符合需求。

  2. 用while循环替代递归
    while(1)实现无限循环接收输入,既符合C语言规范又安全,不会出现栈溢出问题。如果需要让用户主动退出,可以额外加一个输入选项(比如输入特定值退出)。

  3. 简化阶乘计算
    把阶乘循环改成从1到k依次相乘的直观写法,代码可读性更强,也降低了出错概率。

内容来源于stack exchange

火山引擎 最新活动