mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7
1484 字
4 分钟
改错题专项练习
2026-06-01

改错题专项练习#

本篇文章整理了两道典型的 C 语言程序改错题,分别涉及数字位处理和字符串中单词末字母大写转换。每道题目均给出详细的解题思路、错误分析、完整带注释代码以及关键知识点说明。


题目一:取出长整型数中奇数位数字构成新数#

题目描述#

下列给定程序中函数 fun 的功能是:将长整型数中各位上为奇数的数字依次取出,构成一个新数放在 t 中。高位仍在高位,低位仍在低位。

例如:当 s 中的数为 87653142 时,t 中的数为 7531

解题思路#

本题考查长整型数各位数字的提取与重组。核心思路如下:

  1. 初始化:通过指针 t 输出结果,因此需要先对 *t 进行初始化。原程序中可能未初始化,导致结果错误。
  2. 逐位提取:通过 s % 10 取出 s 的个位数字 d
  3. 奇数判断:判断 d 是否为奇数,即 d % 2 == 1。原程序可能误写为 d % 2 == 0
  4. 重组新数:若 d 为奇数,则将 d 乘以相应的权值 sl 加到 *t 中,并将权值 sl 乘以 10。
  5. 继续处理:将 s 除以 10,去掉已经处理过的个位,循环直到 s 为 0。

错误分析#

错误位置错误代码修改为错误原因
错误1*t 未初始化*t = 0;指针 t 所指变量未初始化,会导致结果不可预测。
错误2if (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);
}

关键知识点#

  1. 指针参数的初始化:当函数通过指针参数返回结果时,必须在函数内显式初始化指针所指变量,避免使用未定义的值。
  2. 数字位提取s % 10 取个位,s /= 10 去掉个位,是处理数字各位的常用方法。
  3. 数的重组:通过权值 sl(每次乘 10)将新数字按位组合,实现高位在高位、低位在低位。
  4. 奇偶判断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 函数的功能是将小写英文字母转为对应的大写字母;如果传入不是小写字母,原样返回,不做修改。

解题思路#

本题考查字符串中单词边界的识别与字符修改。核心思路如下:

  1. 标志位 kk = 0 表示当前不在单词中,k = 1 表示当前在单词中。
  2. 遍历字符串:从首字符开始逐个处理字符 *p
  3. 识别单词结束:当 k 为 1(在单词中)且当前字符 *p 是空格时,说明前一个字符是单词的最后一个字母,需要将 *(p-1) 转为大写。
  4. 更新标志位:遇到空格后将 k 置 0,表示离开单词;遇到非空格字符时将 k 置 1,表示进入单词。
  5. 末尾处理:主函数在字符串末尾人为添加了一个空格 chrstr[d] = ' ',确保最后一个单词也能被处理。

错误分析#

错误位置错误代码修改为错误原因
错误1if (*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);
}

关键知识点#

  1. 空格字符与空字符的区别' ' 是空格字符(ASCII 32),'\0' 是字符串结束符(ASCII 0),二者完全不同,不能混淆。
  2. 指针的回退操作*(p-1) 表示当前指针位置的前一个字符,常用于需要修改前一个字符的场景。
  3. 字符串末尾处理技巧:通过在字符串末尾人为添加一个空格,可以统一处理所有单词(包括最后一个单词),避免特殊判断。
  4. toupper 函数:定义在 <ctype.h> 中,将小写字母转为大写字母,非小写字母原样返回。
  5. 标志位法识别单词:使用 k 变量记录”是否在单词中”的状态,是处理单词边界问题的经典方法。

总结#

改错题的解题核心是:

  1. 仔细审题:明确题目要求实现的功能,对比代码找出与功能不符的地方。
  2. 常见错误类型
    • 逻辑错误:条件判断写反(如 == 写成 =< 写成 >,奇偶判断错误等)。
    • 字符常量错误:如 ' ' 误写为 '''\0'
    • 初始化遗漏:指针参数或局部变量未初始化。
    • 下标错误:如 ii-1i+1 混淆。
  3. 验证修改:修改后用题目给出的示例数据运行一遍,确认结果正确。
  4. 不要过度修改:改错题只允许修改错误行,不能改动程序的其他部分,否则可能影响评分。

掌握数字位处理、字符串处理等常见题型,并熟悉标志位、指针操作等技巧,能够有效提高改错题的解题能力。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

改错题专项练习
https://blog.radarweb.top/posts/c/改错题专项练习/
作者
Sherry
发布于
2026-06-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录