程序设计题专项练习
本篇文章整理了三道典型的 C 语言程序设计题,涵盖字符串处理、数组统计和结构体计算等常见考点。每道题目均给出详细的解题思路、完整带注释代码以及关键知识点说明。
题目一:将字符串中奇数下标位的字母转为大写
题目描述
编写函数 fun,其功能是:将 ss 所指字符串中所有下标为奇数位上的字母转换为大写(若该位置上不是字母,则不转换)。
例如:若输入 "abc4EFg",则应输出 "aBc4EFg"。
注意:请勿改动主函数 main 和其它函数中的任何内容,仅在函数 fun 的花括号中填入你编写的若干语句。
解题思路
本题考查字符串遍历与字符大小写转换。核心思路如下:
- 遍历字符串:使用指针
ss遍历字符串,同时用一个整型变量i记录当前字符的下标。 - 判断下标:当
i % 2 == 1时,表示当前字符位于奇数下标位。 - 判断并转换字母:调用
toupper函数将当前字符转为大写。由于toupper对非小写字母原样返回,所以即使当前位置不是字母也不会有副作用。 - 指针后移:每次循环将指针
ss后移一位,下标i加 1,直到遇到字符串结束符'\0'。
完整代码
/*-------------------------------------------------------【程序设计】题目:将字符串中奇数下标位的字母转为大写-------------------------------------------------------*/
#include <stdio.h>#include <string.h>
void fun(char* ss){ /**********Program**********/ for (int i = 0; *ss != '\0'; i++) // 遍历字符串,i 为当前下标 { if (i % 2 == 1) // 判断下标是否为奇数 *ss = toupper(*ss); // 将当前字符转为大写(非字母原样返回) ss++; // 指针后移,处理下一个字符 } /********** End **********/}
void main(){ char tt[81]; printf("\nPlease enter an string within 80 characters:\n"); gets(tt); printf("\n\nAfter changing, the string\n \"%s\"", tt); fun(tt); printf("\nbecomes\n \"%s\"\n", tt);}关键知识点
- 指针与下标的结合使用:在遍历字符串时,可以同时使用指针(访问字符)和整型变量(记录下标),二者配合实现按位置操作。
toupper函数:定义在<ctype.h>中,将小写字母转为大写字母,非小写字母原样返回。使用时无需自行判断是否为字母。- 奇偶判断:
i % 2 == 1判断奇数,i % 2 == 0判断偶数。注意 C 语言中下标从 0 开始,所以下标 1、3、5… 是奇数下标。 - 字符串结束符:
'\0'是字符串的结束标志,遍历字符串时通常以它作为循环终止条件。
题目二:统计各年龄段的人数
题目描述
请编写函数 fun,该函数的功能是:统计各年龄段的人数。N 个年龄通过调用随机函数获得,并放入主函数的 age 数组中。
要求函数把 0~9 岁年龄段的人数放在 d[0] 中,把 10~19 岁年龄段的人数放在 d[1] 中,把 20~29 岁年龄段的人数放在 d[2] 中,依此类推,把 100 岁(含 100 岁)以上年龄的人数都放在 d[10] 中。结果在主函数中输出。
注意:请勿改动 main 函数和其他函数中的任何内容,仅在函数 fun 的花括号中填入你编写的若干语句。
解题思路
本题考查数组遍历与按区间统计。核心思路如下:
- 遍历年龄数组:循环遍历
age数组(共 N 个元素),逐个处理每个年龄。 - 年龄段映射:观察题目要求可以发现,年龄段与数组下标的关系为
下标 = 年龄 / 10:- 0~9 岁 →
0/10 = 0,9/10 = 0,对应d[0] - 10~19 岁 →
10/10 = 1,19/10 = 1,对应d[1] - 依此类推
- 0~9 岁 →
- 特殊处理 100 岁以上:对于 100 岁及以上的年龄,
年龄 / 10的结果为 10(如100/10=10,115/10=11)。但题目要求 100 岁以上都放在d[10],所以需要在统计后将d[11]、d[12]… 等都累加到d[10],或者使用min(年龄/10, 10)作为下标。 - 简化处理:实际上,由于随机函数产生的年龄范围为 0~114(
115 * rnd()取整后最大为 114),114 / 10 = 11,所以需要将 100 岁以上的合并到d[10]。但参考给定代码b[a[i] / 10]++,需要先确保b数组已初始化为 0,并且对 100 岁以上的元素需要特殊处理。
参考代码采用直接 b[a[i] / 10]++ 的方式,但需要注意 b 数组必须先清零,并且当 a[i] / 10 > 10 时应归并到 d[10]。下面的完整代码给出了更严谨的实现。
完整代码
/*-------------------------------------------------------【程序设计】题目:统计各年龄段的人数-------------------------------------------------------*/
#include <stdio.h>
# define N 50# define M 11
void fun(int* a, int* b){ /**********Program**********/ int i; // 步骤1:先将统计数组 b 初始化为 0(防止未初始化导致结果错误) for (i = 0; i < M; i++) b[i] = 0;
// 步骤2:遍历年龄数组,按年龄段统计人数 for (i = 0; i < N; i++) { int idx = a[i] / 10; // 计算年龄段对应的下标 if (idx > 10) // 100 岁以上(idx > 10)统一归入 d[10] idx = 10; b[idx]++; // 对应年龄段的人数加 1 } /********** End **********/}
double rnd(){ static t = 29, c = 217, m = 1024, r = 0; r = (r * t + c) % m; return((double)r / m);}
void main(){ int age[N], i, d[M]; for (i = 0; i < N; i++) age[i] = (int)(115 * rnd()); /* 产生一个随机的年龄数组 */ printf("The original data :\n"); for (i = 0; i < N; i++) printf((i + 1) % 10 == 0 ? "%4d\n" : "%4d", age[i]); /* 每行输出10个数 */ printf("\n\n"); fun(age, d); for (i = 0; i < 10; i++) printf("%4d---%4d :%4d\n", i * 10, i * 10 + 9, d[i]); printf("Over 100 : %4d\n", d[10]);}说明:原参考答案直接使用
b[a[i] / 10]++,假设b数组在主函数中已初始化为 0,且未对 100 岁以上进行归并。为代码严谨起见,上面的实现增加了b数组清零和 100 岁以上归并的处理。若按原题代码的简化写法,可改为:for (int i = 0; i < N; i++)b[a[i] / 10]++;
关键知识点
- 整数除法映射:利用
年龄 / 10整数除法的特性,可以将连续的年龄段映射到数组下标,是一种简洁高效的统计方法。 - 数组初始化:统计类题目中,统计数组必须先清零,否则会累加未定义的初值导致结果错误。
- 边界处理:对于超出预定区间的数据(如 100 岁以上),需要进行特殊处理,通常通过
if判断或min函数将其归并到边界区间。 - 随机数生成:本题使用线性同余法生成伪随机数,主函数中通过
(int)(115 * rnd())产生 0~114 的随机年龄。
题目三:求学生的平均分
题目描述
某学生的记录由学号、8 门课程成绩和平均分组成,学号和 8 门课程的成绩已在主函数中给出,请编写函数 fun,其功能是:求出该学生的平均分,并放入记录的 ave 成员中。
例如:学生的成绩是:85.5, 76, 69.5, 85, 91, 72, 64.5, 87.5,则他的平均分应为 78.875。
注意:请勿改动主函数 main 和其它函数中的任何内容,仅在函数 fun 部位中填入你编写的若干语句。
解题思路
本题考查结构体指针与数组求平均值的计算。核心思路如下:
- 结构体定义分析:结构体
STREC包含三个成员:num[10]:学号(字符串)s[N]:8 门课程成绩(double 数组,N=8)ave:平均分(double)
- 求和:遍历
s数组,累加所有成绩到变量avg中。 - 求平均:将累加和除以课程数
N,得到平均分。 - 赋值:将计算得到的平均分赋给结构体的
ave成员。
注意:参考代码中循环从
i = 1开始,且除以N - 1,这看起来像是题目原本要求只对后 7 门课求平均(即第 0 门不算),但从题目描述”8 门课程成绩”以及示例数据来看,应该是 8 门课全部参与计算。下面给出按 8 门课计算平均分的标准实现。
完整代码
/*-------------------------------------------------------【程序设计】题目:求学生的平均分-------------------------------------------------------*/
#include <stdio.h>
#define N 8
typedef struct{ char num[10]; // 学号 double s[N]; // 8 门课程成绩 double ave; // 平均分} STREC;
void fun(STREC* a){ /**********Program**********/ double sum = 0; // 累加和初始化为 0 int i; for (i = 0; i < N; i++) // 遍历所有 8 门课程成绩 { sum += a->s[i]; // 累加每门课程的成绩 } a->ave = sum / N; // 计算平均分并赋值给 ave 成员 /********** End **********/}
void main(){ STREC s = { "GA005",85.5,76,69.5,85,91,72,64.5,87.5 }; int i; fun(&s); printf("The %s's student data:\n", s.num); for (i = 0; i < N; i++) printf("%4.1f\n", s.s[i]); printf("\nave=%7.3f\n", s.ave);}说明:原参考答案代码如下,循环从
i = 1开始,且除以N - 1:double avg = 0;for (int i = 1; i < N; i++){avg += a->s[i];}a->ave = avg / (N - 1);这种写法计算的是后 7 门课的平均分(不算第 0 门)。但根据题目描述”8 门课程成绩”和示例数据
85.5, 76, 69.5, 85, 91, 72, 64.5, 87.5,全部 8 门课的平均分才是78.875。建议使用上面给出的标准实现(循环从 0 开始,除以 N)。
关键知识点
- 结构体指针访问成员:通过结构体指针访问成员有两种方式:
(*a).成员名a->成员名(更常用,等价于(*a).成员名)
- 结构体数组求平均:先累加所有元素,再除以元素个数,是计算平均值的标准方法。
- 累加变量初始化:累加变量必须初始化为 0(如
double sum = 0;),否则会包含未定义的垃圾值。 - 浮点数运算:成绩使用
double类型存储,保证计算精度。输出时使用%7.3f等格式控制输出位数。 - 结构体初始化:主函数中
STREC s = { "GA005", 85.5, 76, ... }是结构体的初始化方式,按成员顺序依次赋值。
总结
程序设计题的解题核心是:
- 理解题意:仔细阅读题目要求,明确函数需要实现的功能。
- 分析数据结构:根据题目给出的数据结构(如字符串、数组、结构体等)选择合适的处理方法。
- 设计算法:
- 字符串处理:通常使用指针遍历,注意字符串结束符
'\0'。 - 数组统计:注意数组初始化、下标映射、边界处理。
- 结构体处理:熟练使用
->运算符访问成员,注意成员的数据类型。
- 字符串处理:通常使用指针遍历,注意字符串结束符
- 注意细节:
- 变量初始化(特别是累加变量、统计数组)。
- 循环边界(起始值、终止值、步长)。
- 数据类型(int 与 double 的转换)。
- 遵守题目约束:不修改主函数和其它函数,只在指定位置编写代码。
- 验证结果:编写完成后用题目给出的示例数据手动验证,确认输出正确。
掌握字符串处理、数组统计、结构体操作等基础算法,并注意初始化、边界、数据类型等细节,能够应对大部分 C 语言程序设计题。
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时












