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 ; }
问题分析
你的代码主要有两个核心问题:
重复调用
scanf导致输入逻辑混乱
你先执行了两次scanf获取n和k,之后又再次调用scanf来做返回值校验——这相当于要求用户输入两次n和两次k!如果用户只输入了一组n和k,第二次scanf就会读取失败,直接触发"Failed"提示,这就是为什么校验代码一保留程序就出错的原因。递归调用
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; }
修正说明
合并输入与校验逻辑
现在每次调用scanf后立刻判断返回值,用户只需要输入一次n和k,输入失败直接触发错误提示,逻辑清晰且完全符合需求。用while循环替代递归
用while(1)实现无限循环接收输入,既符合C语言规范又安全,不会出现栈溢出问题。如果需要让用户主动退出,可以额外加一个输入选项(比如输入特定值退出)。简化阶乘计算
把阶乘循环改成从1到k依次相乘的直观写法,代码可读性更强,也降低了出错概率。
内容来源于stack exchange




