C语言计算机二级试题—卷001

公共知识

【1】下列叙述中正确的是()。

〖A〗算法的时间复杂度是指算法在执行过程中基本运算的次数
〖B〗算法的时间复杂度是指算法执行所需要的时间
〖C〗算法的时间复杂度是指算法执行的速度
〖D〗算法复杂度是指算法控制结构的复杂程度
试题解读
算法的时间复杂度是指执行算法所需要的计算工作量, 其计算工作量是用算法所执行的基本运算次数来度量的。A项正确。

【2】下列叙述中正确的是()。

〖A〗循环队列是队列的一种链式存储结构
〖B〗循环队列是队列的一种顺序存储结构
〖C〗循环队列中的队尾指针一定大于队头指针
〖D〗循环队列中的队尾指针一定小于队头指针
试题解读
在实际应用中, 队列的顺序存储结构一般采用循环队列的形式。当循环队列满或者为空时:队尾指针=队头指针。B项正确。

【3】某完全二叉树有256个结点, 则该二叉树的深度为()。

〖A〗7
〖B〗8
〖C〗9
〖D〗10
试题解读
根据完全二叉树的性质:具有n个结点的完全二叉树的深度为[log 2n] + 1。本题中完全二叉树共有256个结点, 则深度为[log 2 256] + 1 = 8 + 1 = 9。C项正确。

【4】下列叙述中错误的是()。

〖A〗线性结构也能采用链式存储结构
〖B〗线性结构一定能采用顺序存储结构
〖C〗有的非线性结构也能采用顺序存储结构
〖D〗非线性结构一定不能采用顺序存储结构
试题解读
满二叉树与完全二叉树均为非线性结构, 但可以按照层次进行顺序存储。D项正确。

【5】需求分析的主要任务是()。

〖A〗确定软件系统的功能
〖B〗确定软件开发方法
〖C〗确定软件开发工具
〖D〗确定软件开发人员
试题解读
需求分析是软件开发之前必须要做的准备工作之一。需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望。故需求分析的主要任务是确定软件系统的功能。A项正确。

【6】一个模块直接调用的下层模块的数目称为模块的()。

〖A〗扇入数
〖B〗扇出数
〖C〗宽度
〖D〗作用域
试题解读
扇入数指调用一个给定模块的模块个数。扇出数是指由一个模块直接调用的其他模块数, 即一个模块直接调用的下层模块的数目。B项正确。

【7】将数据和操作置于对象统一体中的实现方式是()。

〖A〗隐藏
〖B〗抽象
〖C〗封装
〖D〗结合
试题解读
对象具有封装性, 从外面看只能看到对象的外部特性, 对象的内部对外是封闭的。即封装实现了将数据和操作置于对象统一体中。C项正确。

【8】采用表结构来表示数据及数据间联系的模型是()。

〖A〗层次模型
〖B〗概念模型
〖C〗网状模型
〖D〗关系模型
试题解读
关系模型采用二维表来表示, 简称表。D项正确。

【9】在供应关系中, 实体供应商和实体零件之间的联系是()。

〖A〗多对多
〖B〗一对一
〖C〗多对一
〖D〗一对多
试题解读
一家供应商可提供多种零件, 一种零件也可被多家供应商提供。所以实体供应商和实体零件之间的联系是多对多。A项正确。

【10】如果定义班级关系如下:

班级(班级号, 总人数, 所属学院, 班级学生)
则使它不满足第一范式的属性是()。
〖A〗班级号
〖B〗班级学生
〖C〗总人数
〖D〗所属学院
试题解读

对于关系模式, 若其中的每个属性都已不能再分为简单项, 则它属于第一范式模式。
题目中"班级"关系的"班级学生"属性, 还可以进行再分, 如学号、姓名、性别、出生日期等, 因此不满足第一范式。B项正确。

专业知识

【11】以下说法正确的是()。

〖A〗C语言只接受十进制的数
〖B〗C语言只接受八进制、十进制、十六进制的数
〖C〗C语言接受除二进制之外任何进制的数
〖D〗C语言接受任何进制的数
试题解读
C可以使用格式控制符%d, %u, %f等接受十进制的数, 使用%o接受八进制的数, 使用%x接受十六进制的数, 本题答案选B。

【12】以下说法错误的是()。

〖A〗由三种基本结构组成的结构化程序不能解决过于复杂的问题
〖B〗由三种基本结构组成的结构化程序能解决一些简单的问题
〖C〗由三种基本结构组成的结构化程序能解决递归问题
〖D〗由三种基本结构组成的结构化程序能解决数学上有解析解的问题
试题解读
顺序结构、选择结构、循环结构是三种基本结构, 由三种基本结构所构成的程序称为结构化程序, 由三种基本结构组成的算法可以解决任何复杂的问题, 选项A错误, 本题答案A

【13】以下说法错误的是()。

〖A〗C语言标识符中可以有多个字母、数字和下划线字符
〖B〗C语言标识符中下划线字符可以出现在任意位置
〖C〗C语言标识符不能全部由数字组成
〖D〗C语言标识符必须以字母开头
试题解读

C语言的合法的标识符的命名规则是:标识符可以由字母、数字和下划线组成, 并且第一个字符必须是字母或下划线。
选项D错误, 本题答案D

【14】以下说法错误的是()。

〖A〗C语言中的常量是指在程序运行过程中经常被用到的变量
〖B〗C语言中的常量是指在程序运行过程中其值不能被改变的量
〖C〗C语言中的常量可以用一个符号名来代表
〖D〗C语言中的常量可以用宏来定义
试题解读
C语言中的常量是指在程序运行过程中其值不能被改变的量, 它可以用宏来定义, 用一个符号名代表, 选项A错误, 选项B、C、D正确, 本题答案A

【15】若有定义:int a = 1234, b = -5678; 用语句 printf("%+-6d%+-6d", a, b); 输出, 以下正确的输出结果是()。

〖A〗+1234 -5678 (中间有一个空格,最后有一个空格)
〖B〗+1234 -5678 (最前面有一个空格,中间有一个空格)
〖C〗+-1234+-5678 (最前面和最后均无空格)
〖D〗1234 -5678 (中间有两个空格,最后有一个空格)
试题解读
printf函数参数包括格式控制字符串和输出参数, 其中格式控制字符串中除了格式控制字符外, 其他字符原样输出, 本题中, 在%和格式字符d之间, +号表示输出的数字带正负号, -号表示输出数据向左对齐, 6表示表示输出宽度, 如果输出数据的宽度不够6, 那么左对齐, 右边补空格, 所以本题输出+1234 - 5678, 中间一个空格, 最后一个空格, 本题答案A

【16】若有定义:double a; float b; short c;

若想把1.2输入给变量a, 3.4输入给变量b, 5678输入给变量c, 程序运行时键盘输入:
1.2 3.4 5678<回车>
则以下正确的读入语句是()。
〖A〗scanf("%lf%lf%d", &a, &b, &c);
〖B〗scanf("%lf%lf%hd", &a, &b, &c);
〖C〗scanf("%lf%f%hd", &a, &b, &c);
〖D〗scanf("%f%f%d", &a, &b, &c);
试题解读
scanf函数用于输入数据, 第一个参数表示输入格式控制, 本题变量a是double类型, 使用格式控制符%lf, 变量b是float类型, 使用%f, 变量c是short类型, 使用%hd, 选项C正确, 本题答案C

【17】有下列程序

#include <stdio.h>
void main() {
    int a = 1, b = 1, c = 1;
    if (a-- || b-- && --c)
        printf("%d,%d,%d\n", a, b, c);
    else
        printf("%d,%d,%d\n", a, c, b);
}

程序执行后的输出结果是()。

〖A〗0,1,0
〖B〗0,1,1
〖C〗0,0,1
〖D〗0,0,0
试题解读
if条件表达式a-- || b-- && --c使用了逻辑或运算符和逻辑与运算符, 由于逻辑与运算符优先级比逻辑或运算符优先级高, 所以条件表达式等价于(a--) || (b-- && --c), 自左向右运算, 执行a--, 由于a初值为1, 所以a--的值为1, 执行完后a的值为0; 又因为逻辑或运算符的短路原则, 当a--的值为1时, 条件为真, 后面的表达式b-- && --c不执行, 程序执行if语句块, 输出a、b、c的值为:0, 1, 1, 本题答案B

【18】有下列程序

#include <stdio.h>
void main() {
    int a = 123456, b;
    while (a) {
        b = a % 10;
        a /= 10;
        switch (b) {
            default:
                printf("%d", b++);
            case 1:
                break;
            case 2:
                printf("%d", b++);
                break;
            case 3:
                printf("%d", b++);
            case 4:
                printf("%d", b++);
            case 5:
                printf("%d", b++);
        }
    }
}

程序执行后的输出结果是()。

〖A〗654321
〖B〗65432
〖C〗65453452
〖D〗654534521
试题解读
程序首先定义整型变量a和b, a的初值为123456, 接着通过while循环, 判断a的值是否为0, 若不为0, 则执行循环体, 每次循环将a当前值的个位数字(a % 10)赋给b, a自身除以10, 再通过switch语句判断b的值执行对应分支语句; 所以对于a的每个个位数, b的取值为6, 5, 4, 3, 2, 1, 当b取值为6时, 执行default, 输出6, 接着继续执行case 1, break退出switch, 执行下一次循环; 当b取值为5时, 执行case 5输出5, 执行下一次循环; 当b取值为4时, 执行case 4输出4, 继续执行case 5输出5, 接着下一次循环; 当b取值为3时, 执行case 3输出3, 执行case 4输出4, 执行case 5输出5; 当b取值为2时, 执行case 2输出2, break跳出switch; 当b取值为1时, 执行break, 此时a的取值为0, 循环终止, 程序输出结果为:65453452, 本题答案C。

【19】有下列程序

#include <stdio.h>
void main() {
    int a = 1, b = -2;
    for (; a-- && b++; )
        printf("%d,%d,", a, b);
    printf("%d,%d", a, b);
}

程序执行后的输出结果是()。

〖A〗0,-1,-1,-1
〖B〗0,-1,-1,0
〖C〗0,-1,-1,0,-1,0
〖D〗0,-1,-1,-1,-1,-1
试题解读

程序定义整型变量a和b, 初值分别是1, -2, for语句中循环条件式为a-- && b++, 由于--和++的优先级高于逻辑与运算符&&, 所以等价于(a--) && (b++), 自左向右运算
第一轮循环, a、b的值为1, -2:首先执行a--, a--的值为1, 执行完后a的值为0, 继续执行b++, b++的值为-2, 执行完后b的值为-1, 整个表达式a-- && b++的值为真, 程序输出0, -1;
接着继续循环
第二轮循环, a、b的值为0, -1:首先执行a--, a--的值为0, 执行完后a的值为-1, 由于a--的值为0, 逻辑与运算的短路原则, 表达式a-- && b++的值一定为假, 表达式b++不再执行, 循环结束, 执行循环体外的printf语句, 输出a、b的值分别为:-1, -1
所以本题输出结果为:0, -1, -1, -1, 本题答案A

【20】有下列程序

#include <stdio.h>
void main() {
    int a = 7, i;
    for (i = 1; i <= 3; i++) {
        if (a > 14)
            break;
        if (a % 2) {
            a += 3;
            continue;
        }
        a = a + 4;
        printf("%d,%d,", i, a);
    }
    printf("%d,%d", i, a);
}

程序执行后的输出结果是()。

〖A〗2,14,3,18,4,18
〖B〗1,14,2,18,3,18
〖C〗2,14,3,18,4,22
〖D〗1,14,2,18,3,18,4,18
试题解读

程序定义整型变量a和i, 其中a的初值为7, for循环中, 循环变量i的取值为1, 2, 3, 循环体中判断a的取值, 当a > 14时, break跳出循环; 当a取值为奇数时, a % 2 == 1, a自增3, continue继续执行循环体; 当a取值为偶数时, a % 2 == 0, a自增4, 输出i和a的值; 所以:i取值为1时, a取值为7, 自增3后a的值为10, 执行下一个循环
i取值为2时, a取值为10, 自增4后a的值为14, 输出2, 14 i取值为3时, a取值为14, 自增4后a的值为18, 输出3, 18 i取值为4时, a取值为18, 循环终止, 输出4, 18
综上, 程序输出:2, 14, 3, 18, 4, 18, 本题答案为A

【21】以下正确的字符常量是()。

〖A〗'\089'
〖B〗'\012'
〖C〗'\0XAB'
〖D〗'\0xab'
试题解读
题意中都以转义字符\开头, \开头的转义字符中, \ddd表示三位八进制数代表的一个ASCII字符, \xhh表示二位十六进制数代表的一个ASCII字符; 选项A中089是不合法的八进制数, 错误; 选项C、D中\0X或\0x不合法, 错误; 选项B表示八进制数012代表的ASCII字符, 正确; 本题答
案B

【22】有下列程序

#include <stdio.h>
void main() {
    char b[] = "happychristmas", k;
    for (k = 0; b[k]; k++) {
        if (b[k] < 'm')
            b[k] = b[k] - 'a' + 'A';
        printf("%c", b[k]);
    }
}
程序执行后的输出结果是()。
〖A〗hAppychristmAs
〖B〗happychristmas
〖C〗HAppyCHrIstmAs
〖D〗HAPPYCHRISTMAS
试题解读
程序定义一个字符数组b, 和一个字符变量k, for循环通过循环变量k, 遍历数组b中的各个字符, 通过if语句判断当前下标为k的字符的ASCII码与字符'm'的大小, 把数组b中ASCII码小于'm'的字符改成大写字母(b[k] = b[k] - 'a' + 'A'), 然后输出b[k], 对于字符串happychristmas, ASCII码小于'm'的字符有:h, a, c, h, i, a, 所以程序输出:HappyCHrIstmAs, 本题答案C

【23】有如下形式的函数

int fun(int a[4][5], int *p[10], int n) {
    ……
}
调用函数之前需要对函数进行说明, 即所谓的函数向前引用说明, 以下对fun函数说明正确的是()。
〖A〗int fun(int b[][5], int *r[], int m);
〖B〗int fun(int a[4][], int *p[10], int n);
〖C〗int fun(int a[][], int *p[], int n);
〖D〗int fun(int a[], int *p[], int n);
试题解读

题意中函数的定义指出了函数名为fun, 返回值为int, 函数包含三个参数, 第一个参数是整型的二维数组, 第二个参数是整型数组, 第三个参数是整型变量, 在定义二维数组时, 必须指定第二维的长度, 所以选项B、C、D错误, 选项A正确, 本题答案A

【24】关于指针, 以下说法正确的是()。

〖A〗可以直接向指针中写入数据
〖B〗若指针指向变量, 则可以向指针所指内存单元写入数据
〖C〗指针可以指向内存中任何位置, 并写入数据
〖D〗两个指针可以通过加运算求和, 形成一个功能更强大的指针
试题解读
C语言中指针就是变量的地址, 它必须有确定的基类型, 当指针指向某个变量时, 才能向其中写入数据, 选项A错误, 选项B正确; 指针除了指向变量外, 还可以赋值为NULL, 表示未指向任何地址, 此时不能写入数据, 另外指针必须有基类型, 只能指向基类型相同的变量, 选项C错误; 指针只能与一个整数进行运算, 即移动指针, 两个指针不能运算, 选项D错误, 本题答案B

【25】有下列程序

#include <stdio.h>
int *f(int *s) {
    s += 1;
    s[1] += 6;
    *s-- += 7;
    return s;
}
void main() {
    int a[5] = { 1, 2, 3, 4, 5 }, *p;
    p = f(a);
    printf("%d,%d,%d,%d", a[1], a[2], *p, p[1]);
}
程序执行后的输出结果是()。
〖A〗2,3,1,2
〖B〗9,9,2,9
〖C〗8,10,2,8
〖D〗9,9,1,9
试题解读
程序定义了一个整型数组a, 它包含5个整型元素, 分别是1, 2, 3, 4, 5, 此时a代表数组的首地址, 另外还定义整型指针p, 将a传给函数f, 在函数f中, 首先将指针s向右移动一个整型变量的长度, 此时s指向元素2(a[1]), s[1](a[2])表示元素3, 自增6后s[1](a[2])的值为9, 表达式*s-- += 7表示将*(s--)指向的元素自增7, 即s[0](a[1])的值为9, s向左移动一个整型变量的长度, 此时s指向元素1(a[0]), 最后将s返回赋给p, 经过函数f的调用可知:p指向数组a的第一个元素, a[1]和a[2]值为9, 综上, 输出结果为:9, 9, 1, 9, 本题答案D

【26】有下列程序

#include <stdio.h>
void swap(int *a, int *b) {
    int *tp, t;
    t = *a;
    *a = *b;
    *b = t;
    tp = a;
    a = b;
    b = tp;
    printf("%d,%d,", *a, *b);
}
void main() {
    int i = 3, j = 7, *p = &i, *q = &j;
    swap(&i, &j);
    printf("%d,%d", *p, *q);
}
程序执行后的输出结果是()。
〖A〗3,7,3,7
〖B〗7,3,7,3
〖C〗3,7,7,3
〖D〗7,3,3,7
试题解读
程序定义两个整型变量i, j, 初值为3, 7, 另外定义两个整型指针变量p, q, 其中p指向i, q指向j, 将i, j的地址传给swap函数, 在swap函数中, a指向i, b指向j, 通过临时变量t交换a和b指向的值, 此时a指向的实参i, b指向的实参j的值发生了交换, 即a指向i的值为7, b指向j的值为3; 再通过临时变量tp交换a和b的指针值, 使得a指向j, b指向i, 所以swap中输出a指向的值为3(j), b指向的值为7(i); swap函数调用结束后, 输出p和q指向的值, 即i, j的值7, 3, 所以程序输出:3, 7, 7, 3, 本题答案C

【27】有下列程序

#include <stdio.h>
#define N 4
int fun(int a[][N]) {
    int i, y = 0;
    for (i = 0; i < N; i++)
        y += a[i][0] + a[i][N - 1];
    for (i = 1; i < N - 1; i++)
        y += a[0][i] + a[N - 1][i];
    return y;
}
void main() {
    int y, x[N][N] = { { 1, 2, 3, 4 }, { 2, 1, 4, 3 }, { 3, 4, 1, 2 }, { 4, 3, 2, 1 } };
    y = fun(x);
    printf("%d", y);
}
程序执行后的输出结果是()。
〖A〗30
〖B〗35
〖C〗40
〖D〗32
试题解读
程序定义一个整型变量y和整型二维数组x, 并对x赋初值, 接着调用函数fun, 在函数fun中, 第一个for循环将数组a的第0列和第N - 1列的所有元素累加到y中, 第二个for循环将数组a的第0行的2, 3和第N - 1行的3, 2累加到y中, 再将y返回, 所以fun函数的功能是将数组a的行列下标为0、N - 1的所有元素累加起来, 即1, 2, 3, 4, 2, 3, 3, 2, 4, 3, 2, 1, 输出30, 本题答案A

【28】有下列程序

#include <stdio.h>
void fun(int a[], int n, int flag) {
    int i = 0, j, t;
    for (i = 0; i < n - 1; i++)
        for (j = i + 1; j < n; j++)
            if (flag ? (a[i] < a[j]) : (a[i] > a[j])) {
                t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
}
void main() {
    int c[10] = { 7, 9, 10, 8, 3, 5, 1, 6, 2, 4 }, i;
    fun(c, 5, 1);
    fun(c + 5, 5, 0);
    for (i = 0; i < 10; i++)
        printf("%d,", c[i]);
}
程序执行后的输出结果是()。
〖A〗3,7,8,9,10,6,5,4,2,1,
〖B〗10,9,8,7,3,1,2,4,5,6,
〖C〗10,9,8,7,6,1,2,3,4,5,
〖D〗1,2,3,4,5,10,9,8,7,6,
试题解读

程序中函数fun的功能是将数组a的n个元素, 按照flag的值进行排序:当flag为0时, 升序排列, 当flag为1时, 降序排列。
main函数中定义数组c, 初始化10个元素的值, 第一次调用fun, flag为1, 即将c的下标为0开始的5个元素降序排列, 第二次调用fun, flag为0, 将c的下标为5开始的5个元素升序排列, 所以数组c的元素为:10, 9, 8, 7, 3, 1, 2, 4, 5, 6, 本题答案B。

【29】有下列程序

#include <stdio.h>
void main() {
    int i, j = 0;
    char a[] = "ab1b23c4d56ef7gh89i9j64k", b[100];
    for (i = 0; a[i]; i++)
        if (a[i] < 'a' || a[i] > 'z')
            b[j++] = a[i];
    for (i = 0; a[i]; i++)
        if (a[i] < '0' || a[i] > '9')
            b[j++] = a[i];
    b[j] = '\0';
    printf("%s", b);
}
程序执行后的输出结果是()。
〖A〗abbcdefghijk123456789964
〖B〗123456789964abbcdefghijk
〖C〗123445667899abbcdefghijk
〖D〗abbcdefghijk123445667899
试题解读
程序定义数组a, b, 其中a使用小写字母和数字构成的字符串完成初始化; 第一个for循环将数组a中所有的非小写字母字符(数字字符)自左向右存放到b数组中, 第二个for循环将数组a中所有的非数字字符(小写字母)自左向右存放到b的后续单元中, 在所有字符后添加空字符, 输出b, 此时b的值为:123456789964abbcdefghijk, 本题答案B

【30】有下列程序

#include <stdio.h>
void main() {
    char v[4][10] = { "efg", "abcd", "mnopq", "hijkl" }, *p[4], t;
    int i, j;
    for (i = 0; i < 4; i++)
        p[i] = v[i];
    for (i = 0; i < 3; i++)
        for (j = i + 1; j < 4; j++)
            if (*p[i] > *p[j]) {
                t = *p[i];
                *p[i] = *p[j];
                *p[j] = t;
            }
    for (i = 0; i < 4; i++)
        printf("%s ", v[i]);
}
程序执行后的输出结果是()。
〖A〗abcd efg hijkl mnopq
〖B〗afg ebcd hnopq mijkl
〖C〗efg abcd mnopq hijkl
〖D〗mijkl hnopq ebcd afg
试题解读
程序首先定义二维字符数组v, 使用四个字符串初始化, 另外定义字符指针数组p, 通过第一个for循环, 将v的四个字符串的首地址赋给p, 第二个for循环通过两层内嵌循环将p中元素指向的字符串首字母进行排序交换, 规则是:将指向的字符串的首字母字符按照字母表中的顺序排序后交换, 注意, 这里交换的是首字母, 而不是整个字符串, 所以程序输出:afg ebcd hnopq mijkl, 本题答案B

【31】有下列程序

#include <stdio.h>
void main() {
    char v[5][10] = { "efg", "abcd", "snopq", "hijkl", "xyz" };
    printf("%s,%c,%s,%c,%s", *v, **(v + 3), v[4] + 2, *(v[2] + 4), v[1] + 1);
}

程序执行后的输出结果是()。

〖A〗efg,h,z,q,bcd
〖B〗efg,d,zyz,w,bbcd
〖C〗efgabcdsnopqhijklxyz,h,z,q,bcd
〖D〗efgabcdsnopqhijklxyz,d,zyz,w,bbcd
试题解读

程序定义一个二维字符数组v, 使用5个字符串初始化, 对于表达式:*v等价于*(v + 0), 输出的是数组v的第一个元素:efg; **(v + 3)等价于*(*(v + 3) + 0), 输出的是数组v的第四个元素的第一个字符:h; v[4]表示数组v的第五个元素, v[4] + 2表示输出从下标2开始的所有字符:z; v[2]表示数组v的第三个元素, *(v[2] + 4)表示数组v的第三个元素的下标为4的字符:q, v[1] + 1表示数组v的第二个元素从下标1开始的子字符串, 即:bcd, 本题输出:efg, h, z, q, bcd, 本题答案A

【32】有下列程序
#include <stdio.h>
#include <string.h>
void main() {
    char a[5][10] = { "efg", "abcd", "mnopq", "hijkl", "rstuvwxyz" };
    char *p[5];
    int i, len;
    for (i = 0; i < 5; i++) {
        p[i] = a[i];
        len = strlen(p[i]);
        printf("%c", p[i][0]);
        printf("%s", p[i] + len / 2);
    }
}
程序执行后的输出结果是()。
〖A〗eeaabmmnhhirrstu
〖B〗efgabcdmnopqhijklrstuvwxyz
〖C〗efgacdmopqhjklrvwxyz
〖D〗eefgaabcdmmnopqhhijklrrstuvwxyz
试题解读

程序定义一个二维字符数组a, 使用5个字符串初始化, 另外定义字符指针数组p, for循环中, 每次将数组a当前下标为i的字符串首地址赋给p[i], 再求得p[i]的长度赋给len, 第一个printf输出p[i]字符串的首字母, 第二个printf输出p[i]字符串下标从len / 2开始的子字符串, 所以:下标i = 0输出:efg
下标i = 1输出:acd
下标i = 2输出:mopq
下标i = 3输出:hjkl
下标i = 4输出:rvwxyz
程序输出:efgacdmopqhjklrvwxyz, 本题答案C

【33】有下列程序

#include <stdio.h>
int f(int x) {
    if (x < 2)
        return 1;
    return x * f(x - 1) + (x - 1) *f(x - 2);
}
void main() {
    int y;
    y = f(4);
    printf("%d\n", y);
}
程序执行后的输出结果是()。
〖A〗11
〖B〗43
〖C〗57
〖D〗53
试题解读

函数f是一个递归函数, 当x >= 2时, 递归调用自身, 返回值为:x * f(x - 1) + (x - 1) * f(x - 2), 当x < 2时, 返回值为1。
main函数中, 调用函数f传入4, 所以y的值是f(4)。
f(4)等价于 4 * f(3) + 3 * f(2)f(3)等价于 3 * f(2) + 2 * f(1)f(2)等价于 2 * f(1) + 1 * f(0)f(0), f(1)等价于1
综上:f(2)等于3, f(3)等于11, f(4)等于53, 本题答案D

【34】有下列程序

#include <stdio.h>
int a = 5;
int func(int d) {
    int b = 5;
    static int c = 5;
    a--;
    b--;
    --c;
    --d;
    return a + b + c + d;
}
void main() {
    int k, a = 4;
    for (k = 0; k < 3; k++)
        printf("%d,", func(a--));
}
程序执行后的输出结果是()。
〖A〗15,12,9,
〖B〗15,13,11,
〖C〗15,11,7,
〖D〗15,15,15,
试题解读

程序定义整型的全局变量a, 初值为5, main函数定义整型局部变量a, 初值也是5, 所以在main函数中, 局部变量a屏蔽全局变量a; func函数中定义局部变量b, 初值为5, 定义静态变量c, 初值为5, 并且在func函数中变量a引用的是全局变量a。
综上, 我们使用a_a代表全局变量a, 使用m_a代表main函数中局部变量a。
void main函数中, k = 0时, a_a = 5, m_a = 4, 调用函数func(4), 函数func中d的值为4, b的值为5, c的值为5, 执行表达式a_a--;
b--;
--c;
--d;
后, a_a的值为4, b的值为4, c的值为4, d的值为3, a + b + c + d的值为15, 程序输出15 k = 1时, a_a = 4, m_a = 3, 调用函数func(3), 函数func中d的值为3, b的值为5, c的值为4(静态变量使用上一次调用结束时的值), 执行表达式a_a--;
b--;
--c;
--d;
后, a_a的值为3, b的值为4, c的值为3, d的值为2, a + b + c + d的值为12, 程序输出12 k = 2时, a_a = 3, m_a = 2, 调用函数func(2), 函数func中d的值为2, b的值为5, c的值为3, 执行表达式a_a--;
b--;
--c;
--d后, a_a的值为2, b的值为4, c的值为2, d的值为1, a + b + c + d的值为9, 程序输出9。
综上, 本题答案:A

【35】有下列程序

#include <stdio.h>
#define S1(x, y) x * y
#define S2(x, y) (x) * (y)
void main() {
    int a = 2, b = 5;
    printf("%d,%d,%d,%d", S1(a + b, a + b), S1(a + b, b + a), S2(a + b, a + b), S2(a + b, b + a));
}
程序执行后的输出结果是()。
〖A〗17,17,49,49
〖B〗17,29,49,49
〖C〗29,29,49,49
〖D〗49,49,49,49
试题解读

对于题意中的宏, 替换如下:S1(a + b, a + b)等价于:a + b * a + b, 即2 + 5 * 2 + 5, 等于17 S1(a + b, b + a)等价于:a + b * b + a, 即2 + 5 * 5 + 2, 等于29 S2(a + b, a + b)等价于:(a + b) * (a + b), 即(2 + 5) * (2 + 5), 等于49 S2(a + b, b + a)等价于:(a + b) * (b + a), 即(2 + 5) * (5 + 2), 等于49
本题答案:B

【36】有下列程序

#include <stdio.h>
#include <string.h>
typedef struct stu {
    char name[9];
    char gender;
    int score;
} STU;
STU a = { "Zhao", 'm', 85 };
STU f() {
    STU c = { "Sun", 'f', 90 };
    strcpy(a.name, c.name);
    a.gender = c.gender;
    a.score = c.score;
    return a;
}
void main() {
    STU b = { "Qian", 'f', 95 };
    b = f();
    printf("%s,%c,%d,%s,%c,%d", a.name, a.gender, a.score, b.name, b.gender, b.score);
}
程序执行后的输出结果是()。
〖A〗Sun,f,90,Sun,f,90
〖B〗Zhao,m,85,Sun,f,90
〖C〗Zhao,m,85,Qian,f,95
〖D〗Sun,f,90,Qian,f,95
试题解读
程序定义结构体类型stu, 定义全局stu变量a, main函数定义局部stu变量b, 并对它们初始化, 调用函数f, 将局部变量c的各个成员值赋给a, 覆盖a的旧值, 并将a的新值返回赋给b, 此时a、b的各个成员值都是:"Sun", 'f', 90, 程序输出:Sun, f, 90, Sun, f, 90, 本题答案A

【37】有下列程序

#include <stdio.h>
typedef struct stu {
    char name[9];
    char gender;
    int score;
} STU;
void f(STU *a) {
    STU c = { "Sun", 'f', 90 }, *d = &c;
    *a = *d;
    printf("%s,%c,%d,", a->name, a->gender, a->score);
}
void main() {
    STU b = { "Zhao", 'm', 85 }, *a = &b;
    f(a);
    printf("%s,%c,%d", a->name, a->gender, a->score);
}
程序执行后的输出结果是()。
〖A〗Zhao,m,85,Zhao,m,85
〖B〗Sun,f,90,Zhao,m,85
〖C〗Zhao,m,85,Sun,f,90
〖D〗Sun,f,90,Sun,f,90
试题解读

程序定义结构体类型stu, main函数定义结构体stu变量b, 并将b的地址赋给指针变量a, 调用函数f, 传入a, 在函数f中, 定义了stu变量c, 并将c的地址赋给d, 再用d指向的值赋给a指向的地址, 接着输出a指向的值, 也就是c的值:Sun, f, 90; 由于函数f的调用通过指针参数a修改了变量b的值, 所以a指向的值也就是b的值等价于c : Sun, f, 90。
本题答案D

【38】若有定义

typedef int *T[10];
T *a;
则以下与上述定义中a类型完全相同的是()。
〖A〗int *a[10];
〖B〗int **a[10];
〖C〗int *(*a)[10];
〖D〗int *a[][10];
试题解读
由题意可知, T是一个数组指针, 即int * [], 所以使用T * a定义, 可知a属于int * *[]类型, 本题答案B。

【39】有下列程序

#include <stdio.h>
void main() {
    int x = 4, y = 2, z1, z2;
    z1 = x && y;
    z2 = x & y;
    printf("%d,%d\n", z1, z2);
}
程序执行后的输出结果是()。
〖A〗1,0
〖B〗1,1
〖C〗1,4
〖D〗4,4
试题解读
&&是逻辑与运算符, x, y的取值为4, 2, 两个都是非0值, 所以x && y的结果为真, 值为1; &是位运算符, x的二进制为0100, y的二进制为0010, 0100 & 0010的结果为0, 本题答案A

【40】有下列程序

#include <stdio.h>
void main() {
    FILE *fp;
    int i, a[6] = { 1, 2, 3, 4, 5, 6 };
    fp = fopen("d.dat", "w+b");
    for (i = 5; i >= 0; i--)
        fwrite(&a[i], sizeof(int), 1, fp);
    rewind(fp);
    fread(&a[3], sizeof(int), 3, fp);
    fclose(fp);
    for (i = 0; i < 6; i++)
        printf("%d,", a[i]);
}
程序执行后的输出结果是()。
〖A〗6,5,4,4,5,6,
〖B〗1,2,3,4,5,6,
〖C〗4,5,6,4,5,6,
〖D〗1,2,3,6,5,4,
试题解读

程序定义数组a, 使用6个元素对其初始化, 接着以写二进制方式打开文件d.dat, 调用fwrite函数将a的6个元素逆序写入文件(654321), 接着调用rewind函数, 将文件指针移动到文件开始位置, 调用fread函数读入3个整数, 逐个存放到a开始下标为3的三个位置, 即a[3] = 6, a[4] = 5, a[5] = 4, 关闭文件, 再次调用for循环输出a, 输出结果为:1, 2, 3, 6, 5, 4。
本题答案:D

编程题

【41】试题一

【41】给定程序中, N名学生的数据已存入类型为STU的结构体数组, 函数fun的作用是:计算出N名学生的平均成绩, 将高于平均分的学生的学号存入p所指的存储单元中, 高于平均分的人数由函数值返回。
请在程序的下划线处填入正确的内容并把下划线删除, 使程序得出正确的结果。
注意:源程序存放在文件BLANK1.C中, 不得增行或删行, 也不得更改程序的结构 !
程序清单
#include <stdio.h>
#include <string.h>
#define N 6
typedef struct
{ char num[5];
  double s;
} STU;


int fun(STU x[N], char p[][5])
{
  int n=0,i;
  double ave=0.0;
  for(i=0; i<N; i++)
/**********found**********/
        ave+= ____(1)____;
  ave/=N;
  for(i=0; i<N; i++)
/**********found**********/
       if(x[i].s ____(2)____)
         {
             strcpy(p[n],x[i].num);
/**********found**********/
              ____(3)____;
         }
    return(n);
}
 main()
{ int i,k;
 STU a[N]={ "z100",78,"z101",92,"z102",77,"z103",87,"z104",66,"z105",85};
 char b[N][5];
 k=fun(a,b);
 for(i=0; i<k;i++)
        puts(b[i]);
}
试题解读

(1) x[i].s
(2) > ave
(3) n++
(1) 根据题意, STU结构体中, num数组存放学生学号, 变量s存放学生成绩。
fun()函数需要计算N个学生的平均成绩ave。
第一个for循环将x中N名学生的成绩累加到ave, 即ave += x[i].s, 循环结束后再除以N。
(2) fun()函数求得N名学生的平均值后, 再次遍历数组x, 将成绩高于平均值ave的学生学号存放到指针p指向的存储单元中, 所以if语句中需要判断x[i].s > ave。
(3) n的初值为0, 每次将成绩高于平均值ave的学生学号使用strcpy拷贝到p指向的第n个存储单元后, 需要对n自增1, 表示下一个可用的存储单元索引, 也表示当前存放到p中的学生学号的个数, 最后会作为函数返回值返回。

【42】试题二

【42】给定程序MODI1.C中, 函数fun的功能是:将a串奇数位置(注意:不是下标)上的字符与b串偶数位置上的字符交叉合并, 形成一个新字符串存入c所指的存储空间。合并过程中, 任何一个字符串到达串尾, 则合并过程结束。
例如, a串为:asderty b串为:zxcvb 则c串为:axdvr
请改正程序中的错误, 使它能得出正确的结果。
注意:不要改动main函数, 不得增行或删行, 也不得更改程序的结构 !
程序清单
#include <stdio.h>
void fun( char *a,char *b,char *c)
{  int i=0,j=0;
   while( a[i]!='\0' && b[i]!='\0')
   {
         c[j++]=a[i];
/************found************/
         if(b[i+1]=='\0')
         c[j++]=b[i+1];
         else
/************found************/
         continue;
if (a[i+1]=='\0')
break;
         i+=2;
   }
/************found************/
   c[j+1]='\0';
}
 main()
{  char a[40]="asderty",b[40]="zxcvb",c[80];
   fun(a,b,c);
   puts(c);
}
试题解读

(1) if (b[i + 1] != '\0')
(2) break;
(3) c[j] = '\0';
(1) 根据题意, fun()函数的每一轮whie循环, 需要将a[i]存放到c[j], b[i + 1]存放到c[j + 1], 直到a[i]或b[i + 1]为空字符为止。
循环最后需要对i自增2, 保证a[i]是a的奇数位置字符, b[i + 1]是b的偶数位置字符, 所以第一处需要修改为:if (b[i + 1] != '\0')
(2) 由(1)可知, else 表示b[i + 1] == '\0', 此时按照题意, 程序应该跳出while循环, 所以continue应该修改为break。
(3) while循环中每次将字符存放到c[j]后, 都对j自增1, 所以j始终指向c最后一个有效字符的下一个位置。
循环结束后只需要对c[j]存放空字符即可, 所以c[j + 1] = '\0'修改为c[j] = '\0'。

【43】试题三

【43】程序中定义了N×N的二维数组, 并已在主函数中赋初值。
请编写函数fun, 其功能是:将a所指数组主对角线上的元素分别乘以2; 次对角线上的元素分别乘以3, 依次放入指针p所指的数组中。计算过程中不得修改a所指数组中的数据。
注意:部分源程序在文件PROG1.C中。
请勿改动主函数main和其他函数中的任何内容, 仅在函数fun的花括号中填入所编写的若干语句。
程序清单:
#include <stdio.h>
#define N  3
#pragma warning(disable:4996)
void NONO( );


void fun( int a[N][N],int *p)
{




}
main()
 {   int a[N][N]={ 1,5,7,2,6,8,3,4,9};
     int b[2*N],i;
     fun(a,b);
     for(i=0;i<2*N;i++)
            printf("%d,",b[i]);
     NONO();
}


void NONO( )
{   int a[N][N];
     int b[2*N],i,j,k;
     FILE *rf, *wf;


     rf = fopen("in.dat","r") ;
     wf = fopen("out.dat","w") ;
     for(k=0; k<9;k++) {
           for(i=0;i<N;i++)
                for(j=0;j<N;j++)
                     fscanf(rf,"%d,",&a[i][j]);
         fun(a,b);
         for(i=0;i<2*N;i++)
              fprintf(wf, "%d,",b[i]);
         fprintf(wf, "\n");
     }
     fclose(rf);
     fclose(wf);
}
void fun(int a[N][N], int *p) {
    int i, k = 0;
    for (i = 0; i < N; i++) {
        p[k++] = a[i][i] * 2;
    }
    for (i = 0; i < N; i++) {
        p[k++] = a[i][N - i - 1] * 3;
    }
}
试题解读

首先需要理解, 题意中二维数组的主对角线元素是指行下标和列下标相等的元素, 次对角线元素是指行下标和列下标之和为N - 1的元素。
接下来编写fun函数, 程序定义两个变量i和k, k初值为0, 通过两个for循环完成题意要求, 第一个for循环遍历二维数组的主对角线元素a[i][i], 乘2后赋值给p[k], 再对k自增1; 第二个for循环遍历二维数组的次对角线元素a[i][N - i - 1], 乘3后赋值给p[k], 再对k自增1。