基于float与if语句的成绩分级程序逻辑错误排查请求
问题排查与修复方案
错误根源分析
1. 区间起始/结束值判断错误
- 核心逻辑错误:
Average分支的条件完全写错,规则中Average对应1.8-2.7,但代码中写成了(grade<=3.7) && (grade>=1.8),错误覆盖了Superior(3.3-3.7)和Good(2.8-3.2)的区间,直接导致高分数被错误归类。 - float精度问题:像3.8、1.3这类十进制小数无法用二进制float精确存储,会变成近似值(比如3.8存储为
3.79999995,1.3存储为1.29999995),直接用>=/<=判断会让边界值不满足预期条件,跳转到错误分支。
2. 负数输入处理错误
现有代码中,负数本应进入Invalid分支,但结合精度问题的干扰,可能导致测试时出现误判。实际scanf("%f")可以正确读取负数,只需明确将负数和超出0.0-4.0范围的值归类为Invalid即可。
修复后的代码
#include<stdio.h> // 定义精度阈值,处理float近似存储的误差问题 #define EPS 1e-6 int main (void){ float grade; printf("\t\tWhat is your grade?\t\t"); // 检查输入是否为有效浮点数 if(scanf("%f",&grade) != 1){ printf("\n\t\tInvalid input..."); return 1; } // 先判断超出有效范围的情况 if (grade < 0.0 - EPS || grade > 4.0 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tInvalid input..."); } else if (grade >= 3.8 - EPS && grade <= 4.0 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tExcellent"); } else if (grade >= 3.3 - EPS && grade <= 3.7 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tSuperior"); } else if (grade >= 2.8 - EPS && grade <= 3.2 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tGood"); } else if (grade >= 1.8 - EPS && grade <= 2.7 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tAverage"); } else if (grade >= 1.3 - EPS && grade <= 1.7 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tBelow Average"); } else if (grade >= 1.0 - EPS && grade <= 1.2 + EPS){ printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tPassing"); } else{ // 剩余情况为0 <= grade < 1.0 printf("\n\t\tInput grade: %.1f",grade); printf("\n\t\tFailure"); } return 0; }
修复要点说明
- 修正区间逻辑:将
Average分支的上限从3.7改为2.7,严格匹配成绩分级规则。 - 处理float精度问题:引入
EPS(1e-6)作为精度阈值,判断时给边界值留出微小误差空间,避免近似存储导致的边界判断失败。 - 提前拦截无效输入:先检查成绩是否小于0或大于4.0,直接归类为Invalid,确保负数和超范围值被正确处理。
- 增加输入有效性校验:判断
scanf的返回值,确保用户输入的是有效浮点数,避免非法输入导致的程序异常。
内容的提问来源于stack exchange,提问作者Jude Joseph Agustino
相关产品推荐
相关产品推荐

