C语言for循环break判断失效及输出循环次数异常问题求助
程序实现要求
- 使用for循环处理5名员工的相关数据
- 拆分两个独立for循环:第一个循环负责加载录入数据,第二个循环负责打印输出结果
- 数据录入循环中,若任意输入字段值为-1,获取到-1后需立即跳出当前循环
- 参照规范数据格式输出内容,使用数组存储所有用户输入数据
现存问题
- break跳出循环逻辑异常:-1判断条件完全失效,无法在输入-1时正常终止录入流程
- 输出打印循环逻辑异常:固定循环5次输出,不会按照用户实际录入的有效信息条数执行输出
问题根因
- 数组越界+判断逻辑错误:
name定义为char[5][10]类型,单条姓名字符串的有效下标范围是0~9,原代码写&name[i][10]直接指向数组边界外的内存,既无法正确存储输入的姓名,后续判断name[i][10] == -1也完全无意义;同时姓名是字符串类型,无法通过单个字符等于-1判断终止,-1终止判断需要针对时薪、工时两个数值字段在输入完成后立刻校验,不能等薪资计算完成后再判断。 - 浮点数判断逻辑风险:直接用
==判断浮点数等于-1存在精度误差,很容易出现输入-1但判断不通过的问题。 - 输出循环硬编码长度:录入循环提前触发break时,有效员工数小于5,原代码固定循环5次会输出未初始化的内存垃圾值。
- 格式化符使用错误:
%c只能输出单个字符,无法输出完整的姓名字符串。 - 数组定义不匹配:薪资相关的float数组长度定义为10,和最大员工数5不匹配,属于冗余定义。
修复后完整代码
#include <stdio.h> int main() { // 所有数组长度统一对齐最大员工数5,姓名字段预留足够存储空间 char name[5][20]; float hourswork[5]; float hourspay[5]; float grosspay[5]; float taxes[5]; float netpay[5]; int valid_count = 0; // 记录实际录入的有效员工数量 int i = 0; // 第一个循环:仅负责数据录入与薪资计算 for (i = 0; i < 5; i++) { printf("请输入员工姓名(输入-1终止录入):\n"); scanf("%s", name[i]); // 判断姓名是否输入终止标识-1 if (name[i][0] == '-' && name[i][1] == '1' && name[i][2] == '\0') { break; } printf("请输入时薪:\n"); scanf("%f", &hourspay[i]); // 数值输入后立刻判断终止标识 if (hourspay[i] < 0) { break; } printf("请输入工作时长:\n"); scanf("%f", &hourswork[i]); if (hourswork[i] < 0) { break; } // 所有字段校验通过后再计算薪资 if (hourswork[i] <= 40) { grosspay[i] = hourspay[i] * hourswork[i]; } else { grosspay[i] = (40 * hourspay[i]) + (((hourswork[i] - 40) * 1.5) * hourspay[i]); } taxes[i] = grosspay[i] * 0.2; netpay[i] = grosspay[i] - taxes[i]; valid_count++; } // 第二个循环:仅负责结果打印,遍历次数为实际有效录入数 for (i = 0; i < valid_count; i++) { printf("\n%s 的薪资明细:\n", name[i]); printf("时薪:%.2f\n", hourspay[i]); printf("工作时长:%.2f\n", hourswork[i]); printf("税前总薪资:%.2f\n", grosspay[i]); printf("税费:%.2f\n", taxes[i]); printf("税后实发薪资:%.2f\n\n", netpay[i]); } return 0; }
核心改动说明
- 修正姓名存储的越界问题:字符串输入直接传入数组首地址
name[i],不再取偏移10的越界内存地址 - 调整终止判断时机:每完成一个字段的输入立刻校验是否为终止值,无需等待全字段输入、薪资计算完成后再判断
- 新增有效计数变量
valid_count:每成功完成一条完整的员工数据录入就计数+1,输出循环仅遍历有效计数范围内的条目,避免输出垃圾值 - 修正姓名输出格式错误:将输出姓名的格式化符从
%c改为%s,支持输出完整姓名字符串 - 统一数组长度:所有存储员工数据的数组长度统一为最大支持员工数5,消除冗余定义
- 优化浮点数判断逻辑:将浮点数
== -1的判断改为< 0,规避浮点数存储精度导致的判断失效问题 - 严格拆分录入、输出两个独立for循环,两个循环分别只做数据加载、结果打印的逻辑,职责完全分离
内容的提问来源于stack exchange,提问作者Harvey Yang
相关产品推荐
相关产品推荐

