C语言程序循环使用scanf时冻结 无法执行后续代码
问题根因与修复方案
你遇到的并非scanf输入冻结,而是两个常见的C语言开发误区共同导致的现象:
1. 打印未生效的原因
C标准输出默认采用行缓冲机制,你写的printf("Loop terminated.");未加换行符\n,也没有手动调用fflush(stdout)刷新缓冲区,内容会暂存于内存中不会输出到屏幕,导致你误判程序卡在scanf阶段,实际上代码已经执行到后续逻辑。
修复方式只需给打印内容加换行符即可立即看到输出:
printf("Loop terminated.\n");
2. 程序实际死循环的两个问题
2.1 locatePump函数逻辑错误
你当前写的while循环条件完全不符合「查找当前可达最远加油站」的需求,同时存在数组越界漏洞:
- 循环条件
range >= disPump[i] && range < disPump[i+1]逻辑倒置,绝大多数输入下要么一次都不进入循环,要么会无限自增i,访问超出disPump数组长度的内存空间,读到的垃圾值会导致循环永远无法退出 - 没有做数组边界判断,
i+1最大可到pumps,超出数组下标合法范围0~pumps-1,属于未定义行为
修复后的locatePump参考:
int locatePump(int range, int disPump[], int pumps, int distCovered){ int max_reach = distCovered + range; int last_valid_idx = -1; // 遍历所有加油站,找当前可达的最远站点 for(int i = 0; i < pumps && disPump[i] <= max_reach; i++){ last_valid_idx = i; } // 无可达站点直接返回错误标记,避免上层死循环 if(last_valid_idx == -1) return -1; return disPump[last_valid_idx] - distCovered; }
2.2 calcRefuel无限循环漏洞
你当前写的while(1)没有错误分支退出逻辑,一旦locatePump返回异常值(比如0),永远无法满足(distCovered+range) >= distance的退出条件,程序会永久卡死。
修复后的calcRefuel参考:
int calcRefuel(int distance, int range, int disPump[], int pumps){ // 冒泡排序逻辑不变 for(int i = 0; i < pumps - 1; i++){ for(int j = 0; j < pumps - i - 1; j++){ if(disPump[j] > disPump[j+1]){ int temp = disPump[j]; disPump[j] = disPump[j+1]; disPump[j+1] = temp; } } } int distCovered = 0; int refill = 0; while(1){ int add_dist = locatePump(range, disPump, pumps, distCovered); // 无可达加油站直接返回错误标记 if(add_dist == -1) return -1; distCovered += add_dist; refill++; if((distCovered + range) >= distance) break; } return refill; }
3. 额外规范优化
你当前代码没有在main函数前声明calcRefuel、locatePump两个函数,属于C语言不规范写法,建议在main前添加前置声明:
int calcRefuel(int distance, int range, int disPump[], int pumps); int locatePump(int range, int disPump[], int pumps, int distCovered);
内容的提问来源于stack exchange,提问作者Dirghayu Joshi
相关产品推荐
相关产品推荐

