【国二】【C语言】改错题中考察switch的用法、do while执行条件的用法
题目 1:switch 表达式错误 + case 穿透(核心考点:switch 表达式需为 “整型 / 字符型”,非布尔值;case 需加 break)
原题代码(功能:根据输入数字 1-3 输出对应等级,输入其他数字输出 “无效”)
#include <stdio.h>
int main() {int score;printf("输入等级数字(1-3):");scanf("%d", &score);// 错误点1:switch表达式用了布尔判断(结果只有0/1),无法匹配case 1/2/3switch(score >=1 && score <=3) { case 1: printf("优秀\n"); // 错误点2:缺少break,会穿透到case 2case 2: printf("良好\n");case 3: printf("合格\n");// 错误点3:无default分支,输入其他值时无输出}return 0;
}
错误分析
- switch 表达式错误:
score >=1 && score <=3
是 “关系表达式”,结果只能是0
(假)或1
(真),无法匹配case 1/2/3
,导致逻辑完全错误; - case 穿透:
case 1
和case 2
后无break
,即使表达式修正,输入 1 也会连续输出 “优秀、良好、合格”; - 缺少 default:输入 4、5 等无效值时,switch 无任何分支执行,不符合 “输出无效” 的功能需求。
修正代码
#include <stdio.h>
int main() {int score;printf("输入等级数字(1-3):");scanf("%d", &score);switch(score) { // 修正:直接用变量score(整型)作为表达式case 1: printf("优秀\n"); break; // 加break防止穿透case 2: printf("良好\n"); break;case 3: printf("合格\n"); break;default: printf("无效\n"); // 补充default处理无效值}return 0;
}
题目 2:do-while 循环条件错误 + switch 分支不完整(核心考点:do-while 循环终止条件逻辑;switch 覆盖所有可能值)
原题代码(功能:循环输入字符,直到输入‘q’退出;输入字母输出 “A”,数字输出 “0”,其他字符输出 “?”)
#include <stdio.h>
#include <ctype.h> // 包含isalpha()、isdigit()函数
int main() {char ch;do {printf("输入字符(输入q退出):");ch = getchar();// 错误点1:未处理缓冲区换行符,导致循环多执行一次if (ch == 'q') break;switch(1) { // 错误点2:switch表达式为常量1,永远只执行case 1case isalpha(ch): printf("A\n"); break; // 错误点3:case后必须是“常量”,不能是函数case isdigit(ch): printf("0\n"); break;default: printf("?\n");}} while (ch != 'q'); // 错误点4:循环条件逻辑矛盾(已用break退出,且未处理换行符)return 0;
}
错误分析
- do-while 缓冲区问题:
getchar()
会读取输入的 “换行符\n
”,若不处理,输入一个字符后,下次循环会自动读取\n
,导致多输出一次 “?”; - switch 表达式错误:
switch(1)
是常量表达式,永远只进入case 1
,但case isalpha(ch)
是 “变量”(isalpha(ch)
结果为 0 / 非 0),不符合 “case 后必须是常量” 的语法规则; - 循环条件冗余:已用
if(ch=='q') break
退出,while(ch!='q')
逻辑冗余,且未解决换行符问题。
修正代码
#include <stdio.h>
#include <ctype.h>
int main() {char ch;do {printf("输入字符(输入q退出):");ch = getchar();if (ch == 'q') break;// 修正1:switch表达式用“条件判断结果”,case后用常量0/1switch(1) {case 1: // 先判断是否为字母if (isalpha(ch)) {printf("A\n");break;}// 字母不成立则判断是否为数字if (isdigit(ch)) {printf("0\n");break;}// 都不成立则执行defaultprintf("?\n");break;}getchar(); // 修正2:读取缓冲区的换行符,避免循环多执行} while (1); // 修正3:用“死循环+break”逻辑,更清晰return 0;
}
题目 3:do-while 循环条件逻辑颠倒 + switch case 值不匹配(核心考点:do-while 循环 “先执行后判断” 的特性;case 值与表达式值一致)
原题代码(功能:循环输入 1-5 的整数,计算输入数字的累加和,输入 0 时退出并输出总和)
#include <stdio.h>
int main() {int num, sum = 0;do {printf("输入数字(1-5累加,0退出):");scanf("%d", &num);// 错误点1:switch表达式用num,但case值为字符'1'-'5'(ASCII值与整数1-5不匹配)switch(num) {case '1': sum += 1; break;case '2': sum += 2; break;case '3': sum += 3; break;case '4': sum += 4; break;case '5': sum += 5; break;case 0: printf("总和:%d\n", sum); break;default: printf("输入错误!\n");}} while (num == 0); // 错误点2:循环条件颠倒,输入0时直接退出,无法执行case 0的输出return 0;
}
错误分析
- switch case 值不匹配:
num
是整数变量(输入 1 时值为1
),但case '1'
是字符常量(ASCII 值为49
),两者永远不相等,导致 1-5 的输入都进入default
; - do-while 循环条件颠倒:
while(num == 0)
表示 “当 num 为 0 时继续循环”,但需求是 “输入 0 时退出”,逻辑完全相反,且会导致输入 0 时先执行 case 0(输出总和),再判断循环条件为真,继续循环(无限要求输入)。
修正代码
#include <stdio.h>
int main() {int num, sum = 0;do {printf("输入数字(1-5累加,0退出):");scanf("%d", &num);switch(num) { // 修正1:case用整数常量,与num类型匹配case 1: sum += 1; break;case 2: sum += 2; break;case 3: sum += 3; break;case 4: sum += 4; break;case 5: sum += 5; break;case 0: printf("总和:%d\n", sum); break;default: printf("输入错误!\n");}} while (num != 0); // 修正2:循环条件改为“num不为0时继续”,符合退出逻辑return 0;
}
总结:高频错误点与解题共性
以上题目均围绕原题目核心考点展开,解题时可紧扣以下 3 个共性步骤:
- 先查 switch 的 2 个 “硬规则”:
- 表达式必须是整型 / 字符型(不能是布尔判断、浮点型);
- case 后必须是常量 / 常量表达式(不能是变量、函数调用),且需加
break
防止穿透,必要时补default
。
- 再查 do-while 的 “逻辑与细节”:
- 循环条件是否与 “业务需求” 一致(如 “输入 0 退出” 对应
while(num!=0)
,而非==
); - 是否处理输入缓冲区残留(如
getchar()
后的换行符,需额外读取); - 利用 “先执行后判断” 特性,确认循环体是否会少执行 / 多执行(如原题目
while(ch=='\n')
导致只执行 1 次)。
- 循环条件是否与 “业务需求” 一致(如 “输入 0 退出” 对应
- 最后结合 “业务功能” 验证:明确代码要实现的功能(如原题目 “根据 sort=-1/0/1 输出 #/?/*”),反向推导表达式、分支、循环条件是否符合逻辑,排除 “语法正确但逻辑错误” 的情况。