计算机二级C语言考试模拟试题
考试时间:120分钟 总分:100分

选择题(每小题1分,共40分)
-
下列叙述中正确的是。 A. 循环队列是队列的一种链式存储结构 B. 循环队列是队列的一种顺序存储结构 C. 循环队列是非线性结构 D. 循环队列是一种逻辑结构
-
下列关于二叉树的叙述中,正确的是。 A. 叶子节点总是比度为2的节点少一个 B. 叶子节点总是比度为2的节点多一个 C. 度为2的节点总是比叶子节点多一个 D. 度为2的节点总是比叶子节点少一个
-
下列排序方法中,最坏情况下时间复杂度达到O(n²)的是。 A. 堆排序 B. 快速排序 C. 冒泡排序 D. 希尔排序
-
下列数据结构中,能够按照“先进后出”原则组织数据的是。 A. 循环队列 B. 栈 C. 队列 D. 有序链表
(图片来源网络,侵删) -
软件设计中模块划分应遵循的准则是。 A. 低耦合、高内聚 B. 高耦合、低内聚 C. 高耦合、高内聚 D. 低耦合、低内聚
-
支持数据库各种操作的软件系统称为。 A. 操作系统 B. 编译系统 C. 数据库管理系统 D. 数据库应用系统
-
在E-R图中,用来表示实体联系的图形是。 A. 矩形 B. 椭圆形 C. 菱形 D. 三角形
-
在C语言中,以下不合法的用户标识符是。 A. _123 B. For C. sizeof D. abc
(图片来源网络,侵删) -
若有定义
int a = 5, b = 2;,则表达式a % b + a / b的值是。 A. 3 B. 3.5 C. 4 D. 2 -
设有定义
char s[] = "Hello";,则sizeof(s)和strlen(s)的值分别是。 A. 5, 5 B. 6, 5 C. 5, 6 D. 6, 6
... (选择题共40题,此处省略其他30题,通常考察C语言基础语法、数据类型、运算符、流程控制、数组、函数、指针等知识点)
程序填空题(每空2分,共18分)
【程序说明】 以下程序的功能是:从键盘上输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到屏幕上,输入 "Hello World!",输出 "HELLO WORLD!"。
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int i, len;
printf("请输入一个字符串: ");
// 1. 使用gets函数从键盘读取一行字符串到str中
gets(str);
// 2. 计算字符串的长度
len = __________;
for (i = 0; i < len; i++) {
// 3. 如果当前字符是小写字母
if (str[i] >= 'a' && str[i] <= 'z') {
// 4. 将其转换为大写字母
str[i] = __________;
}
}
printf("转换后的字符串: %s\n", str);
return 0;
}
请将横线处缺少的部分补充完整。
程序修改题(每小题3分,共12分)
【程序说明】 以下程序的功能是:找出一个3x3矩阵中的最大值及其所在的行号和列号,程序中有错误,请修改。
#include <stdio.h>
int main() {
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int max, row, col;
int i, j;
// 错误点1: max的初始值
max = a[0][0];
row = 0;
col = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
// 错误点2: 比较逻辑
if (a[i][j] > max) {
max = a[i][j];
row = i;
col = j;
}
}
}
printf("最大值是: %d\n", max);
// 错误点3: 输出格式
printf("位置是: 第%d行, 第%d列\n", row, col);
return 0;
}
要求:
- 将错误点1的下方语句修改正确。
- 将错误点2的下方语句修改正确。
- 将错误点3的下方语句修改正确。
- 不得增删行,不得更改程序的结构。
程序设计题(共30分)
【程序说明】
请编写函数 fun,其功能是:将一个字符串中所有连续的数字字符提取出来,并组成一个新的字符串,原字符串为 "a1b23c456",提取后得到的新字符串为 "123456"。
函数原型为:
void fun(char *str, char *result);
str 是源字符串,result 用于存放提取出的数字字符串。
要求:
- 请编写
fun函数。 - 在
main函数中已经完成了字符串的输入和输出,你只需编写fun函数即可。
#include <stdio.h>
#include <string.h>
void fun(char *str, char *result) {
// 请在此处编写代码
}
int main() {
char str[100], result[100] = {""}; // 初始化result为空字符串
printf("请输入一个字符串: ");
gets(str);
fun(str, result);
printf("提取出的数字字符串是: %s\n", result);
return 0;
}
参考答案及解析
选择题
- B,解析:循环队列使用一组地址连续的存储单元依次存放队列中的元素,是顺序存储结构,它利用了队列的顺序存储和循环的特性。
- B,解析:在任意一棵二叉树中,度为0的叶子节点数总是比度为2的节点数多1。
- C,解析:冒泡排序在最坏情况下(如数组完全逆序),需要进行 n(n-1)/2 次比较和交换,时间复杂度为 O(n²),堆排序、快速排序、希尔排序的平均时间复杂度可达到 O(n log n)。
- B,解析:栈的特点是“先进后出”(FILO)。
- A,解析:软件设计原则中,高内聚意味着模块内部功能紧密相关,低耦合意味着模块之间相互依赖程度低。
- C,解析:数据库管理系统是位于用户与操作系统之间的数据管理软件。
- C,解析:在E-R图中,实体用矩形表示,属性用椭圆形表示,实体间的联系用菱形表示。
- C,解析:
sizeof是C语言的关键字,不能用作用户标识符。 - A,解析:
a % b是取余运算,5 % 2结果为1。a / b是整除运算,5 / 2结果为2。1 + 2 = 3。 - B,解析:
sizeof计算的是数组所占用的总字节数,char str[100]会分配100字节,其中99个用于存放字符,1个用于存放字符串结束符\0,sizeof(s)是6(对于 "Hello")或101(对于char str[100],此处题目有歧义,但通常考试会明确字符串长度)。strlen计算的是字符串的长度,即遇到\0之前的字符个数,不包括\0。"Hello"的长度是5。注意:gets函数不安全,现代C标准已弃用,但二级考试中仍可能出现。- 修正:
char s[] = "Hello";,则sizeof(s)是6(包括\0),strlen(s)是5,如果题目是char s[100]; gets(s);,且输入 "Hello",则sizeof(s)是100,strlen(s)是5,根据常见出题意图,此处最可能考察的是sizeof对数组的计算,所以答案是 B. 6, 5。
- 修正:
程序填空题
gets(str)或fgets(str, sizeof(str), stdin)(考试环境通常用gets)strlen(str)'a'或'a'(或str[i] - ('a' - 'A'))str[i] - 32或str[i] - ('a' - 'A')或toupper(str[i])(需要包含ctype.h)
完整代码:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int i, len;
printf("请输入一个字符串: ");
gets(str);
len = strlen(str);
for (i = 0; i < len; i++) {
if (str[i] >= 'a' && str[i] <= 'z') {
str[i] = str[i] - 32; // 或者 str[i] = 'A' + (str[i] - 'a');
}
}
printf("转换后的字符串: %s\n", str);
return 0;
}
程序修改题
-
错误点1:
max = a[0][0];修改为:max = a[0][0];(原代码正确,但通常这类题会有一个明显错误,可能是题目描述有误,或者另一个常见错误是max = 0;,如果矩阵都是负数就会出错,我们假设原代码是正确的,或者这个点本身没问题,重点看下面。)- 更正后的错误点1:如果原代码是
max = 0;,则应修改为max = a[0][0];,根据题目描述,我们假设原代码是正确的,可能题目想考察的是其他点。
- 更正后的错误点1:如果原代码是
-
错误点2:
if (a[i][j] > max)修改为:if (a[i][j] > max)(原代码逻辑正确。)-
重新审视题目:原代码逻辑基本正确,但考试中的“错误”往往很隐蔽,一个经典的错误是:循环边界写错。
for (i = 0; i <= 3; i++),但这里没有,另一个可能是变量初始化,我们假设原代码中max的初始值是错的,max = 0;,那么修改点1就是max = a[0][0];。 -
最终判断:根据常见的出题陷阱,最可能的错误是 错误点3 的输出格式,因为行号和列号通常从1开始计数,而代码中是从0开始的。
-
-
错误点3:
printf("位置是: 第%d行, 第%d列\n", row, col);修改为:printf("位置是: 第%d行, 第%d列\n", row + 1, col + 1);
总结修改后的代码:
#include <stdio.h>
int main() {
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int max, row, col;
int i, j;
// 错误点1修改: 将max初始化为第一个元素
max = a[0][0];
row = 0;
col = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
// 错误点2修改: (原代码正确,假设无此错误或已修正)
if (a[i][j] > max) {
max = a[i][j];
row = i;
col = j;
}
}
}
printf("最大值是: %d\n", max);
// 错误点3修改: 行号和列号从1开始显示
printf("位置是: 第%d行, 第%d列\n", row + 1, col + 1);
return 0;
}
程序设计题
思路:
- 定义一个指针
p遍历源字符串str。 - 定义一个指针
q指向结果字符串result的起始位置,用于写入数字字符。 - 循环遍历
str,直到遇到字符串结束符\0。 - 在循环中,判断当前字符
*p是否是数字字符(*p >= '0' && *p <= '9')。 - 如果是数字字符,则将其赋值给
*q,q指针后移。 - 循环结束后,需要在
result字符串的末尾手动添加字符串结束符\0。 - 返回即可。
参考代码:
#include <stdio.h>
#include <string.h>
void fun(char *str, char *result) {
char *p = str; // 指针p用于遍历源字符串
char *q = result; // 指针q用于指向结果字符串的当前位置
while (*p != '\0') {
// 判断当前字符是否为数字
if (*p >= '0' && *p <= '9') {
*q = *p; // 将数字字符复制到结果字符串中
q++; // q指针后移
}
p++; // p指针后移,继续遍历
}
*q = '\0'; // 在结果字符串末尾添加结束符
}
int main() {
char str[100], result[100] = {""}; // 初始化result为空字符串
printf("请输入一个字符串: ");
gets(str);
fun(str, result);
printf("提取出的数字字符串是: %s\n", result);
return 0;
}
解析:
- 指针遍历:使用指针
p和q来遍历和构建字符串,比使用数组下标更符合C语言指针操作的精髓,也是考试的重点。 - 数字判断:
*p >= '0' && *p <= '9'是判断一个字符是否为数字的常用方法。 - 字符串结束符:这是C语言字符串操作中至关重要的一步,任何对字符串的修改操作,最后都必须确保字符串以
\0否则printf等函数可能会越界访问,导致不可预知的错误。
