来自网络,联系侵删
1484 字
4 分钟
改错题专项练习
改错题专项练习
本篇文章整理了两道典型的 C 语言程序改错题,分别涉及数字位处理和字符串中单词末字母大写转换。每道题目均给出详细的解题思路、错误分析、完整带注释代码以及关键知识点说明。
题目一:取出长整型数中奇数位数字构成新数
题目描述
下列给定程序中函数 fun 的功能是:将长整型数中各位上为奇数的数字依次取出,构成一个新数放在 t 中。高位仍在高位,低位仍在低位。
例如:当 s 中的数为 87653142 时,t 中的数为 7531。
解题思路
本题考查长整型数各位数字的提取与重组。核心思路如下:
- 初始化:通过指针
t输出结果,因此需要先对*t进行初始化。原程序中可能未初始化,导致结果错误。 - 逐位提取:通过
s % 10取出s的个位数字d。 - 奇数判断:判断
d是否为奇数,即d % 2 == 1。原程序可能误写为d % 2 == 0。 - 重组新数:若
d为奇数,则将d乘以相应的权值sl加到*t中,并将权值sl乘以 10。 - 继续处理:将
s除以 10,去掉已经处理过的个位,循环直到s为 0。
错误分析
| 错误位置 | 错误代码 | 修改为 | 错误原因 |
|---|---|---|---|
| 错误1 | *t 未初始化 | *t = 0; | 指针 t 所指变量未初始化,会导致结果不可预测。 |
| 错误2 | if (d % 2 == 0) | if (d % 2 == 1) | 题目要求取出奇数位数字,原代码取的是偶数位数字。 |
完整代码
/*-------------------------------------------------------【程序改错】题目:取出长整型数中奇数位数字构成新数-------------------------------------------------------*/#include <stdio.h>
void fun(long s, long* t){ int d; long sl = 1; /***********FOUND***********/ *t = 0; // 【修改1】初始化 *t 为 0,否则结果会包含未定义的值 while (s > 0) { d = s % 10; // 取出 s 的个位数字 /***********FOUND***********/ if (d % 2 == 1) // 【修改2】判断 d 是否为奇数(原代码错写为 == 0) { *t = d * sl + *t; // 将奇数数字 d 按权值 sl 加到 *t 中 sl *= 10; // 权值乘以 10,准备处理下一位 } s /= 10; // 去掉 s 的个位 }}
main(){ long s, t; printf("\nPlease enter s:"); scanf("%ld", &s); fun(s, &t); printf("The result is: %ld\n", t);}关键知识点
- 指针参数的初始化:当函数通过指针参数返回结果时,必须在函数内显式初始化指针所指变量,避免使用未定义的值。
- 数字位提取:
s % 10取个位,s /= 10去掉个位,是处理数字各位的常用方法。 - 数的重组:通过权值
sl(每次乘 10)将新数字按位组合,实现高位在高位、低位在低位。 - 奇偶判断:
d % 2 == 1判断奇数,d % 2 == 0判断偶数,注意区分。
题目二:将字符串中每个单词的最后一个字母改成大写
题目描述
下列给定的程序中,fun 函数的功能是:将 p 所指的字符串中每个单词的最后一个字母改成大写(这里的”单词”是指有空格隔开的字符串)。
例如:若输入 "I am a student to take the examination",则应输出 "I aM A studenT tO takE thE examinatioN"。
注:toupper 函数的功能是将小写英文字母转为对应的大写字母;如果传入不是小写字母,原样返回,不做修改。
解题思路
本题考查字符串中单词边界的识别与字符修改。核心思路如下:
- 标志位
k:k = 0表示当前不在单词中,k = 1表示当前在单词中。 - 遍历字符串:从首字符开始逐个处理字符
*p。 - 识别单词结束:当
k为 1(在单词中)且当前字符*p是空格时,说明前一个字符是单词的最后一个字母,需要将*(p-1)转为大写。 - 更新标志位:遇到空格后将
k置 0,表示离开单词;遇到非空格字符时将k置 1,表示进入单词。 - 末尾处理:主函数在字符串末尾人为添加了一个空格
chrstr[d] = ' ',确保最后一个单词也能被处理。
错误分析
| 错误位置 | 错误代码 | 修改为 | 错误原因 |
|---|---|---|---|
| 错误1 | if (*p == '') 或类似错误 | if (*p == ' ') | 判断是否为空格应用空格字符 ' ',而不是空字符串。 |
| 错误2 | *(p) = toupper(*(p)) 或类似错误 | *(p - 1) = toupper(*(p - 1)); | 题目要求改的是单词的”最后一个字母”,即当前字符的前一个字符,应使用 *(p-1)。 |
完整代码
/*-------------------------------------------------------【程序改错】题目:将字符串中每个单词的最后一个字母改成大写-------------------------------------------------------*/#include <stdlib.h>#include <string.h>#include <conio.h>#include <ctype.h>#include <stdio.h>
void fun(char* p){ int k = 0; // k 为标志位:0 表示不在单词中,1 表示在单词中 for (; *p; p++) // 遍历字符串,直到遇到结束符 '\0' if (k) // 当前在单词中 { /***********FOUND***********/ if (*p == ' ') // 【修改1】判断当前字符是否为空格(原代码错写为空字符) { k = 0; // 遇到空格,离开单词,重置标志位 /***********FOUND***********/ *(p - 1) = toupper(*(p - 1)); // 【修改2】将单词最后一个字母(即前一字符)转为大写 } } else k = 1; // 之前不在单词中,现在遇到非空格字符,进入单词}
void main(){ char chrstr[64]; int d; system("CLS"); printf("\nPlease enter an English sentence within 63 letters: "); gets(chrstr); d = strlen(chrstr); chrstr[d] = ' '; // 在字符串末尾人为添加一个空格,确保最后一个单词也能被处理 chrstr[d + 1] = 0; // 添加字符串结束符 '\0' printf("\nBofore changing:\n %s", chrstr); fun(chrstr); printf("\nAfter changing:\n %s", chrstr);}关键知识点
- 空格字符与空字符的区别:
' '是空格字符(ASCII 32),'\0'是字符串结束符(ASCII 0),二者完全不同,不能混淆。 - 指针的回退操作:
*(p-1)表示当前指针位置的前一个字符,常用于需要修改前一个字符的场景。 - 字符串末尾处理技巧:通过在字符串末尾人为添加一个空格,可以统一处理所有单词(包括最后一个单词),避免特殊判断。
toupper函数:定义在<ctype.h>中,将小写字母转为大写字母,非小写字母原样返回。- 标志位法识别单词:使用
k变量记录”是否在单词中”的状态,是处理单词边界问题的经典方法。
总结
改错题的解题核心是:
- 仔细审题:明确题目要求实现的功能,对比代码找出与功能不符的地方。
- 常见错误类型:
- 逻辑错误:条件判断写反(如
==写成=,<写成>,奇偶判断错误等)。 - 字符常量错误:如
' '误写为''或'\0'。 - 初始化遗漏:指针参数或局部变量未初始化。
- 下标错误:如
i与i-1、i+1混淆。
- 逻辑错误:条件判断写反(如
- 验证修改:修改后用题目给出的示例数据运行一遍,确认结果正确。
- 不要过度修改:改错题只允许修改错误行,不能改动程序的其他部分,否则可能影响评分。
掌握数字位处理、字符串处理等常见题型,并熟悉标志位、指针操作等技巧,能够有效提高改错题的解题能力。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐












