2015年3月全国计算机等级考试《二级C语言程序设计》真题及详解
(考试时间120分钟 满分100分)
一、选择题(每题1分,共40分)
1某二叉树的中序序列为DCBAEFG,后序序列为DCBGFEA,则该二叉树的深度(根结点在第1层)为( )。
A.5
B.4
C.3
D.2
【答案】B
【解析】二叉树的后序序列为DCBGFEA,则A为根结点。中序序列为DCBAEFG,则DCB为左子树结点,EFG为右子树结点。同理B为C父结点,C为D父结点。根据分析,可画出左子树,同理E为F父结点,F为G父结点。根据分析,可画出右子树,易知二叉树深度为4层。答案选择B选项。
2设有定义:
struct{int n;float x;}s[2],m[2]={{10,2.8},{0,0.0}};
则以下赋值语句中正确的是( )。
A.s[0]=m[1];
B.s=m;
C.s.n=m.n;
D.s[2].x=m[2].x;
【答案】A
【解析】定义了结构体类型数组s,长度为2,结构体类型数组m,长度为2,并对数组m进行了初始化。同类型的结构体可以直接用变量名实现赋值,A项正确;数组名为数组首地址,地址常量之间不可以相互赋值,B项错误;数组名为地址常量不是结构体变量,不能引用成员,C项错误;s[2]与m[2]数组越界,D项错误。答案选择A选项。
3关于C语言标识符,以下叙述错误的是( )。
A.标识符可全部由数字组成
B.标识符可全部由下划线组成
C.标识符可全部由小写字母组成
D.标识符可全部由大写字母组成
【答案】A
【解析】C语言标识符只能由字母、数字、下划线构成,且只能以字母、下划线开头,故答案选择A选项。
4以下程序段中的变量已定义为int类型,则
sum=pAd=5;
pAd=sum++,++pAd,pAd++;
printf("%d\n",pAd);
程序段的输出结果是( )。
A.6
B.4
C.5
D.7
【答案】D
【解析】自增和自减运算符的两种用法:前置运算,运算符放在变量之前,规则是先使变量的值增(或减)1,然后以变化后表达式的值参与其他运算;后置运算,运算符放在变量之后,规则是变量先参与其他运算,然后再使变量的值增(或减)1。执行pAd=sum++,sum++是后置自增,执行完后,pAd=5,sum=6;++pAd和pAd++语句中没有其他运算,即效果相同,pAd分别加1,两句执行完后,pAd=7。答案选择D选项。
5设循环队列为Q(1:m),其初始状态为front=rear=m。经过一系列入队与退队运算后,front=20,rear=15。现要在该循环队列中寻找最小值的元素,最坏情况下需要比较的次数为( )。
A.5
B.6
C.m-5
D.m-6
【答案】D
【解析】循环队列是队列的一种顺序存储结构,用队尾指针rear指向队列中的队尾元素,用队首指针指向队首元素的前一个位置,因此,从队首指针front指向的后一个位置直到队尾指针rear指向的位置之间所有的元素均为队列中的元素,队列初始状态为front=rear=m,当front=20,rear=15时,队列中有m-20+15=m-5个元素,最坏情况下需要比较次数为m-6次。答案选择D选项。
6以下选项中,合法的C语言常量是( )。
A.1.234
B.'C++'
C."\2.0
D.2Kb
【答案】A
【解析】C语言中的常量:①整型常量,用不带小数点的数字表示;②实型常量,用带小数点的数字表示;③字符型常量,用带有单引号的一个字符表示;④字符串常量,用一对双引号括起来的一串字符。1.234为实型常量,A项正确;'C++'不合法,若改成"C++"则为字符串常量,B项错误;"\2.0不合法,不是任何类型常量,C项错误;2Kb不合法,若加上双引号"2Kb"为字符串常量,D项错误。答案选择A选项。
7以下选项中,不能对主函数中变量i和j的值进行交换的程序是( )。
A.
#include <stdio.h>
void swap(int *p,int *q)
{
int *t;
*t=*p;
*p=*q;
*q=*t;
}
main()
{
int i=10,j=20,*a=&i,*b=&j;
swap(a,b);
printf("i=%d j=%d\n",i,j);
}
B.
#include <stdio.h>
void swap(int *p,int *q)
{
int t;
t=*p;
*p=*q;
*q=t;
}
main()
{
int i=10,j=20,*a=&i,*b=&j;
swap(a,b);
printf("i=%d j=%d\n",i,j);
}
C.
#include <stdio.h>
#include <stdlib.h>
void swap(int *p,int *q)
{
int *t;
t=(int *) malloc(sizeof(int));
*t=*p;
*p=*q;
*q=*t;
free(t);
}
main()
{
int i=10,j=20;
swap(&i,&j);
printf("i=%d j=%d\n",i,j);
}
D.
#include <stdio.h>
void swap(int *p,int *q)
{
int t;
t=*p;
*p=*q;
*q=t;
}
main()
{
int i=10,j=20,*x=&i,*y=&j;
swap(x,y);
printf("i=%d j=%d\n",i,j);
}
【答案】A
【解析】A项与C项的区别在于A项在创建临时指针t时,并没有对t进行初始化,也没有对t正确开辟内存,导致程序异常,不能得到正确结果;B项,调用函数传入的是i与j地址,函数体内交换的是地址内元素,临时变量t为整型变量,能实现i与j值交换;C项,调用函数传入的是i与j地址,函数体内交换的是地址内元素,临时变量t为整型指针,且已正确开辟内存,能实现i与j值交换;D项与B项相同,能实现i与j值交换。答案选择A选项。
8C语言中,最基本的数据类型包括( )。
A.整型、实型、逻辑型
B.整型、字符型、数组
C.整型、实型、字符型
D.整型、实型、结构体
【答案】C
【解析】C语言中,最基本的数据类型包括整型、实型、字符型,答案为C选项。
9下列叙述中错误的是( )。
A.算法的时间复杂度与算法所处理数据的存储结构有直接关系
B.算法的空间复杂度与算法所处理数据的存储结构有直接关系
C.算法的时间复杂度与空间复杂度有直接关系
D.算法的时间复杂度与算法程序执行的具体时间是不一致的
【答案】C
【解析】算法的时间复杂度是指执行算法所需要的计算工作量。数据的存储结构直接决定数据输入,因此会影响算法所执行的基本运算次数,A项正确;算法的空间复杂度是指执行这个算法所需要的内存空间,其中包括输入数据所占的存储空间,B项正确;算法的时间复杂度与空间复杂度没有直接关系,C项错误;算法程序执行的具体时间受到所使用的计算机、程序设计语言以及算法实现过程中的许多细节影响,而算法的时间复杂度与这些因素无关,所以算法的时间复杂度与算法程序执行的具体时间是不一致的,D项正确。答案选择C选项。
10以下能正确输出字符a的语句是( )。
A.printf("%s","a");
B.printf("%s",'a');
C.printf("%c","a");
D.printf("%d",'a');
【答案】A
【解析】“格式控制串”用来指定每个输出项的输出格式,%s对应字符串,%c对应字符,%d对应整型。双引号里面的内容为字符串"a",单引号里面的内容为字符'a'。答案选择A选项。
11字符数组a和b中存储了两个字符串,判断字符串a和b是否相等,应当使用的是( )。
A.if(strcmp(a,b)==0)
B.if(strcpy(a,b))
C.if(a==b)
D.if(a=b)
【答案】A
【解析】C语言中,判断字符串是否相等,使用字符串比较函数strcmp(),不能使用相等操作符“==”。strcmp(s1,s2)函数比较s1和s2所指字符串的大小时,若串s1>串s2,函数值大于0(正数);若串s1=串s2,函数值等于0;若串s1<串s2,函数值小于0(负数)。答案选择A选项。
12设有定义:int x=11,y=12,z=0;,以下表达式值不等于12的是( )。
A.(z,x,y)
B.(z=x,y)
C.z=(x,y)
D.z=(x==y)
【答案】D
【解析】逗号表达式的计算过程是从左到右逐个求每个表达式的值,取最右边一个表达式的值作为该逗号表达式的值。赋值运算结合性为由右向左结合,赋值运算符左值为变量,右值为变量或常量或表达式,且左右两边数据类型相同才能实现赋值。成功实现赋值后以左值为返回值。逻辑表达式成立则返回1,不成立返回0。D选项逻辑表达式x==y不成立,则z=0,表达式值为0。B选项中的赋值运算符优先级大于逗号运算符,因此x赋值给z,z=11,再计算逗号表达式,取后面一个值y作为表达式值。C选项逗号表达式(x,y)取y值为表达式值,然后赋值给z=12,表达式值为12。A选项逗号表达式(z,x,y)取y值为表达式值12。答案选择D选项。
13下列叙述中正确的是( )。
A.存储空间连续的数据结构一定是线性结构
B.存储空间不连续的数据结构一定是非线性结构
C.没有根结点的非空数据结构一定是线性结构
D.具有两个根结点的数据结构一定是非线性结构
【答案】D
【解析】A项错误,数据结构线性与否与存储空间是否连续没有直接关系,如二叉树可以用一片连续的空间来存储,但二叉树为非线性结构;B项错误,线性表的链式存储结构可以用不连续的空间来存储,但线性表为线性结构;C项错误,没有根结点的非空数据结构一定不是线性结构;D项正确,线性结构有且只有一个根结点,具有两个根结点的结构一定是非线性结构。答案选择D选项。
14以下选项中,合法的实数是( )。
A.4.5E2
B.E1.3
C.7.11E
D.1.2E1.2
【答案】A
【解析】实型常量用带小数点的数字表示,其值有两种表达形式,分别为十进制小数形式和指数形式。十进制小数形式由数字和小数组成,必须有小数点,且小数点的位置不受限制。指数形式由十进制数加阶码标志“e”或“E”以及阶码(只能为整数,可以带符号)组成。4.5E2为指数形式实数,A项正确。E1.3阶码标志前缺少十进制数,并且阶数不是整数,B项错误。7.11E缺少阶数,C项错误。1.2E1.2阶数不是整数,D项错误。答案选择A选项。
15以下选项中叙述正确的是( )。
A.函数体必须由{开始
B.C程序必须由main语句开始
C.C程序中的注释可以嵌套
D.C程序中的注释必须在一行完成
【答案】A
【解析】函数体是函数首部下面的花括号内的部分,所以函数体必须由{开始,A选项正确。一个源程序文件可以包括预处理命令、全局声明、函数定义,程序总是从main函数开始执行的,不是main语句,B选项错误。函数可以嵌套,注释不能嵌套,C选项错误。C程序中允许两种注释,以//开头的单行注释;以/*开始,以*/结束的块式注释,D选项错误。答案选择A选项。
16在源程序的开始处加上“#include<stdio.h>”进行文件引用的原因,以下叙述正确的是( )。
A.stdio.h文件中包含标准输入输出函数的函数说明,通过引用此文件以便能正确使用printf、scanf等函数
B.将stdio.h中标准输入输出函数链接到编译生成的可执行文件中,以便能正确运行
C.将stdio.h中标准输入输出函数的源程序插入到引用处,以便进行编译链接
D.将stdio.h中标准输入输出函数的二进制代码插入到引用处,以便进行编译链接
【答案】A
【解析】“stdio.h”文件中包含标准输入输出函数的函数说明,预处理指令#include<stdio.h>是指程序可以在该文件中找到printf,scanf等函数,答案选择A选项。
17下面属于白盒测试方法的是( )。
A.边界值分析法
B.基本路径测试
C.等价类划分法
D.错误推测法
【答案】B
【解析】白盒测试是把程序看成装在一只透明的白盒子里,测试者完全了解程序的结构和处理过程。它根据程序的内部逻辑来设计测试用例,检查程序中的逻辑通路是否都按预定的要求正确地工作。白盒测试的主要技术有逻辑覆盖测试、基本路径测试等,B选项正确。常用的黑盒测试方法和技术有:等价类划分法、边界值分析法、错误推测法和因果图等,ACD三项错误。答案选择B选项。
18有以下程序(其中的strstr()函数头部格式为:char* strstr(char* p1,char* p2)确定p2字符串是否在p1中出现,并返回p2第一次出现的字符串首地址):
#include <stdio.h>
#include <string.h>
char *a="you";
char *b="Welcome you to Beijing!";
main()
{
char *p;
p=strstr(b,a)+strlen(a)+1;
printf("%s\n",p);
}
程序的运行结果是( )。
A.to Beijing!
B.you to Beijing!
C.Welcome you to Beijing!
D.Beijing!
【答案】A
【解析】调用strstr函数,返回值为a指向的字符串在b指向的字符串中第一次出现的位置,并将此地址赋给指针p。strlen()函数求字符串的实际长度(不包含结束标志)。strstr函数返回的地址下标值为8,加上a长度3,再加1,指针P指向的地址下标值为12,输出:to Beijing!,答案选择A选项。
19有以下程序:
#include <stdio.h>
void change(int * array,int len)
{
for(;len>=0;len--)array[len]-=1;
}
main()
{
int i, array[5]={2,2};
change(array,4);
for(i=0;i<5;i++)printf("%d,",array[i]);
printf("\n");
}
程序运行后的输出结果是( )。
A.1,1,-1,-1,-1,
B.1,0,-1,1,-1,
C.1,1,1,1,1,
D.1,-1,1,-1,1,
【答案】A
【解析】在main()函数中,首先给一维数组array赋初值[2,2,0,0,0],再调用change函数,对array数组中的每一个数进行减1处理,最后使用for循环语句输出数组元素的值,答案选择A选项。
20有以下程序:
#include <stdio.h>
main()
{
int i,data;
scanf("%d",&data);
for(i=0;i<5;i++)
{
if(i<data) continue;
printf("%d,",i);
}
printf("\n");
}
程序运行时,从键盘输入:3<回车>后,程序输出结果为( )。
A.3,4,
B.1,2,3,4,
C.0,1,2,3,4,5,
D.0,1,2,
【答案】A
【解析】continue语句只能用在循环结构中,其作用是结束本次循环,即不再执行循环体中continue语句之后的语句,而是立即转入对循环条件的判断与执行。本题执行过程为:输入3,则data=3;执行for循环,i=0,if条件成立,结束本次循环,不输出i值,执行下一次循环;直到i>=3,if条件不成立,依次输出i值3,4,;直到i=5退出for循环。答案选择A选项。
21设序列长度为n,在最坏情况下,时间复杂度为O(log2n)的算法是( )。
A.二分法查找
B.顺序查找
C.分块查找
D.哈希查找
【答案】A
【解析】对长度为n的线性表排序,最坏情况下,二分法查找时间复杂度为O(log2n);顺序查找时间复杂度为O(n);分块查找时间复杂度与分块规则有关;哈希查找时间复杂度为O(1),因其通过计算哈希函数来定位元素位置,所以只需一次即可。答案选择A选项。
22有以下程序:
#include <stdio.h>
main()
{
int x;
scanf("%d",&x);
if(x>10) printf("1");
else if(x>20) printf("2");
else if(x>30) printf("3");
}
若运行时输入:35<回车>,则输出结果是( )。
A.123
B.2
C.3
D.1
【答案】D
【解析】程序执行过程为:输入35<回车>,scanf函数从键盘读入35赋值给x,对if条件进行判断,35>10,条件成立,输出1,不再执行下面的else if语句,程序结束。答案选择D选项。
23以下非法的字符常量是( )。
A.'\\n'
B.'\101'
C.'\x21'
D.'\0'
【答案】A
【解析】C语言允许使用一些以特殊形式出现的字符常量,使用'\n'来表示换行,'\n'实际上是一个字符,它的ASCII码值为10,不存在'\\n'用法。答案选择A选项。
24有以下程序:
#include <stdio.h>
#define S(x) x *x
main()
{
int k=5,j=2;
printf("%d,%d\n",S(k+j+2),S(j+k+2));
}
程序的运行结果是( )。
A.21,18
B.81,81
C.21,21
D.18,18
【答案】A
【解析】带参数的宏的替换过程是,用宏调用提供的实参字符串直接置换宏定义命令行中相应形参字符串,非形参字符保持不变。S(k+j+2)被置换成k+j+2*k+j+2,计算时先计算2*k,结果为21;S(j+k+2)被置换成j+k+2*j+k+2,计算时先计算2*j,结果为18。程序的运行结果是21,18。答案选择A选项。
25一名雇员就职于一家公司,一个公司有多名雇员,则实体公司和实体雇员之间的联系是( )。
A.1:1联系
B.1:m联系
C.m:1联系
D.m:n联系
【答案】B
【解析】实体集之间的联系分为3类:一对一联系(1:1)、一对多联系(1:m)、多对多联系(m:n)。题目中一名雇员就职于一家公司,一个公司有多名雇员,公司与雇员之间的联系为一对多(1:m)联系。答案选择B选项。
26将E-R图转换为关系模式时,E-R图中的实体和联系都可以表示为( )。
A.属性
B.键
C.关系
D.域
【答案】C
【解析】采用E-R方法得到的全局概念模型是对信息世界的描述,为了适合关系数据库系统的处理,必须将E-R图转换成关系模式。E-R图是由实体、属性和联系组成,而关系模式中只有一种元素——关系。答案选择C选项。
27以下针对全局变量的叙述错误的是( )。
A.全局变量的作用域是从定义位置开始至源文件结束
B.全局变量是在函数外部任意位置上定义的变量
C.用extern说明符可以限制全局变量的作用域
D.全局变量的生存期贯穿于整个程序的运行期间
【答案】C
【解析】在不同编译单位内用extern说明符来扩展全局变量的作用域,extern可以将全局变量作用域扩展到其他文件,而不是限制全局变量的作用域。答案选择C选项。
28有以下程序:
#include <stdio.h>
main()
{
char *s="120119110";
int n0,n1,n2,nn,i;
n0=n1=n2=nn=i=0;
do
{
switch(s[i++])
{
default:nn++;
case '0':n0++;
case '1':n1++;
case '2':n2++;
}
}while(s[i]);
printf("n0=%d,n1=%d,n2=%d,nn=%d\n",n0,n1,n2,nn);
}
程序的运行结果是( )。
A.n0=3,n1=8,n2=9,nn=1
B.n0=2,n1=5,n2=1,nn=1
C.n0=2,n1=7,n2=10,nn=1
D.n0=4,n1=8,n2=9,nn=1
【答案】A
【解析】本题执行过程为:s[0]='1',匹配case '1',n1=1,n2=1;s[1]='2',匹配case '2',n2=2;s[2]='0',匹配case '0',n0=1,n1=2,n2=3;s[3]='1',匹配case '1',n1=3,n2=4;s[4]='1',匹配case '1',n1=4,n2=5;s[5]='9',匹配default,nn=1,n0=2,n1=5,n2=6;s[6]='1',匹配case '1',n1=6,n2=7;s[7]='1',匹配case '1',n1=7,n2=8;s[8]='0',匹配case '0',n0=3,n1=8,n2=9;s[9]='\0',退出循环。输出n0,n1,n2,nn为3,8,9,1。答案选择A选项。
29在最坏情况下( )。
A.快速排序的时间复杂度比冒泡排序的时间复杂度要小
B.快速排序的时间复杂度比希尔排序的时间复杂度要小
C.希尔排序的时间复杂度比直接插入排序的时间复杂度要小
D.快速排序的时间复杂度与希尔排序的时间复杂度是一样的
【答案】C
【解析】快速排序与冒泡排序的时间复杂度均为O(n2),A项错误;快速排序比希尔排序的时间复杂度要大(O(n2)>O(n1.5)),B、D项错误;希尔排序的时间复杂度比直接插入排序的时间复杂度要小(O(n1.5)<O(n2)),C项正确。答案选择C选项。
30有以下程序:
#include <stdio.h>
main()
{
int x=0x13;
if(x=0x18)printf("T");
printf("F");
printf("\n");
}
程序运行后的输出结果是( )。
A.TF
B.T
C.F
D.TFT
【答案】A
【解析】x=0x18为赋值表达式,十六进制数0x18非0,故x非0,if条件成立输出T,之后再输出F与回车符。程序运行后的输出结果是TF。答案选择A选项。
31以下关于宏的叙述错误的是( )。
A.宏替换不具有计算功能
B.宏是一种预处理指令
C.宏名必须用大写字母构成
D.宏替换不占用运行时间
【答案】C
【解析】宏名习惯采用大写字母,以便与一般变量区别,但是并没有规定一定要用大写字母,答案选择C选项。
32有以下程序:
#include <stdio.h>
int fun(char *s)
{
char *p=s;
while(*p++!='\0');
return(p-s);
}
main()
{
char *p="01234";
printf("%d\n",fun(p));
}
程序的运行结果是( )。
A.6
B.5
C.4
D.3
【答案】A
【解析】程序执行过程为:定义字符串指针p并为其初始化为"01234",调用函数fun(p),将指针传入函数。fun函数功能即返回字符串首地址与结束符下一个地址之差,也即是字符串长度加1。输出地址差为6,答案选择A选项。
33计算机软件包括( )。
A.算法和数据
B.程序和数据
C.程序和文档
D.程序、数据及相关文档
【答案】D
【解析】计算机软件由两部分组成:①机器可执行的程序和数据;②机器不可执行的,与软件开发、运行、维护、使用等有关的文档。答案选择D选项。
34有以下程序:
#include <stdio.h>
main()
{
int i, array[5]={3,5,10,4};
for(i=0;i<5;i++)printf("%d,",array[i] &3);
printf("\n");
}
程序运行后的输出结果是( )。
A.3,1,2,0,0,
B.3,5,10,4,0,
C.3,3,3,3,0,
D.3,2,2,2,0,
【答案】A
【解析】在对数组进行初始化时,如果在声明数组时给出了长度,但没有给所有的元素赋予初始值,那么C语言将自动对余下的元素赋初值0,则array={3,5,10,4,0}。按位与运算“&”,当参加运算的两个二进制数的对应位都为1,则该位的结果为1,否则为0。将数组元素与3按位与,即3&3=3,5&3=1,10&3=2,4&3=0,0&3=0。for循环输出与运算结果:3,1,2,0,0,。答案选择A选项。
35以下叙述正确的是( )。
A.do-while语句构成的循环,当while语句中的表达式值为0时结束循环
B.do-while语句和while-do构成的循环功能相同
C.while-do语句构成的循环,当while语句中的表达式值为非0时结束循环
D.do-while语句构成的循环,必须用break语句退出循环
【答案】A
【解析】B项错误,do-while语句先执行循环体,再判断循环条件语句,while-do循环先判断循环条件语句,再执行循环体;C项错误,do-while语句构成的循环,while语句中的表达式值为0时结束循环;D项错误,do-while语句除了可以使用break语句退出循环外,还可以使用循环条件语句,当不满足循环条件时退出循环。答案选择A选项。
36关于地址和指针,以下说法正确的是( )。
A.通过强制类型转换可以将一种类型的指针变量赋值给另一种类型的指针变量
B.可以取一个常数的地址赋值给同类型的指针变量
C.可以取一个表达式的地址赋值给同类型的指针变量
D.可以取一个指针变量的地址赋值给基类型相同的指针变量
【答案】A
【解析】常数的地址存储在内存的常量区,常量区存储的都是常量,值都是不可修改的,所以直接取常量的地址赋给指针变量没有任何意义,C语言也不允许这样做,编译会出错,B项错误;表达式的值存储在临时变量中,内存中存在专门用来存储临时变量的区域,对这块地址进行操作也是没有意义的,C语言不允许这样做,编译会出错,C项错误;可以取一个指针变量的地址,但是指针变量的地址属于指针,只能赋值给指针类型的指针变量,D项错误。答案选择A选项。
37下面描述不属于软件特点的是( )。
A.软件是一种逻辑实体,具有抽象性
B.软件在使用中不存在磨损、老化问题
C.软件复杂性高
D.软件使用不涉及知识产权
【答案】D
【解析】软件具有以下特点:①软件是一种逻辑实体,具有抽象性;②软件没有明显的制作过程;③软件在使用期间不存在磨损、老化问题;④软件对硬件和环境具有依赖性;⑤软件复杂性高,成本昂贵;⑥软件开发涉及诸多的社会因素,如知识产权等。答案选择D选项。
38以下程序的功能是:通过调用calc函数,把所求得的两数之和值放入变量add中,并在主函数中输出。
#include <stdio.h>
void calc(float x,float y,float *sum)
{
______=x+y;
}
main ()
{
float x,y,add;
scanf("%f%f",&x,&y);
calc(x,y,&add);
printf("x+y=%f\n",add);
}
calc函数中下划线处应填入的是( )。
A.*sum
B.sum
C.&sum
D.add
【答案】A
【解析】程序的执行过程为:从键盘读入两个float类型数据,分别赋给x,y,调用函数calc将x与y的值与add变量地址传入函数,地址赋给指针sum,函数体中将两数之和放入指针指向的地址,指针正确的引用形式为:*sum,这表示变量,可以被赋值。所以横线处填写*sum。答案选择A选项。
39有以下程序:
#include <stdio.h>
main()
{
char c;
for(;(c=getchar())!='#';)putchar(++c);
}
执行时如输入为:abcdefg##<回车>,则输出结果是( )。
A.abcdefg
B.bcdefgh$
C.bcdefgh$$
D.bcdefgh
【答案】D
【解析】for循环每次将函数getchar()的输入值赋给变量c,如果不等于'#',则执行putchar(++c),即将当前变量c的ASCII码加1后,再输出改变后的变量c的值。当变量c的值等于'#',则终止循环,所以输出应该是bcdefgh。答案选择D选项。
40有以下程序:
#include <stdio.h>
void fun(int *x,int s, int e)
{
int i,j,t;
for(i=s,j=e;i<j;i++,j--)
{
t=*(x+i);
*(x+i)=*(x+j);
*(x+j)=t;
}
}
main()
{
int m[]={0,1,2,3,4,5,6,7,8,9},k;
fun(m,0,3);
fun(m+4,0,5);
fun(m,0,9);
for(k=0;k<10;k++)printf("%d",m[k]);
}
程序的运行结果是( )。
A.4567890123
B.3210987654
C.9876543210
D.0987651234
【答案】A
【解析】程序的执行过程为:定义数组m,并为其赋初值,数组长度为10。调用函数fun(m,0,3)将数组首地址传入函数,函数实现将数组下标值从0到3的元素首尾倒置,for循环结束之后数组为m={3,2,1,0,4,5,6,7,8,9}。调用函数fun(m+4,0,4)将数组下标值为4的元素地址传入函数,函数实现将数组下标值从4到9的元素首尾倒置,for循环结束之后数组为m={3,2,1,0,9,8,7,6,5,4}。调用函数fun(m,0,9)将数组首地址传入函数,函数实现将数组下标值从0到9的元素首尾倒置,for循环结束之后数组为m={4,5,6,7,8,9,0,1,2,3}。依次输出数组元素,结果为4567890123。答案选择A选项。
二、程序填空题(共18分)
下列给定程序的功能是调用fun函数建立班级通信录。通信录中记录每位学生的编号、姓名和电话号码。班级人数和学生信息从键盘读入,每个人的信息作为一个数据块写到名为myfile5.dat的二进制文件中。
请在程序的下画线处填入正确的内容并将下画线删除,使程序得出正确的结果。
注意:
不得增行或删行,也不得更改程序的结构!
【试题源程序】
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct
{
int num;
char name[10];
char tel[10];
}STYPE;
void check();
/**********found**********/
int fun(①______ *std)
{
/**********found**********/
②______ *fp; int i;
if((fp=fopen("myfile5.dat","wb"))==NULL)return(0);
printf("\nOutput data to file! \n");
for(i=0;i<N;i++)
/**********found**********/
fwrite(&std[i],sizeof(STYPE),1, ③______);
fclose(fp);
return(1);
}
void main()
{
STYPE s[10]={ {1,"aaaaa","111111"}, {1,"bbbbb","222222"}, {1,"ccccc","333333"}, {1,"ddddd","444444"}, {1,"eeeee","555555"} };
int k;
k=fun(s);
if(k==1)
{
printf("Succeed!");
check();
}
else printf("Fail!");
}
void check()
{
FILE *fp; int i;
STYPE s[10];
if((fp=fopen("myfile5.dat","rb"))==NULL)
{
printf("Fail! \n");
exit(0);
}
printf("\nRead file and output to screen: \n");
printf("\n num name tel\n");
for(i=0;i<N;i++)
{
fread(&s[i],sizeof(STYPE),1,fp);
printf("%6d %s %s\n",s[i].num, s[i].name,s[i].tel);
}
fclose(fp);
}
答:
①STYPE
②FILE
③fp
【解析】
填空1:根据主函数中的调用函数fun(s)可知,函数fun()的形参应为结构体类型,因此填入STYPE。
填空2:fp是指向文件类型的指针变量,因此填入FILE。
填空3:函数fwrite调用的一般形式为“fwrite(buffer,size,count,fp);”,其中,fp表示文件指针。
三、程序修改题(共18分)
下列给定程序中,函数fun的功能是:从s所指字符串中,找出t所指字符串的个数作为函数值返回。例如,当s所指字符串中的内容为“abcdabfab”,t所指字符串的内容为“ab”,则函数返回整数3。
请改正程序中的错误,使它能得出正确的结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构!
【试题源程序】
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
int fun(char *s, char *t)
{
int n;
char *p,*r;
n=0;
while(*s)
{
p=s;
r=t;
while(*r)
/**********found**********/
if(*r==*p){r++; p++}
else break;
/**********found**********/
if(r=='\0')
n++;
s++;
}
return n;
}
void main()
{
char s[100],t[100]; int m;
system("CLS");
printf("\nPlease enter strings:");
scanf("%s",s);
printf("\nPlease enter substrings:");
scanf("%s",t);
m=fun(s,t);
printf("\nThe result is:m=%d\n", m);
}
答:
(1)错误:if(*r==*p){r++;p++}
正确:if(*r==*p){r++;p++;}
(2)错误:if(r=='\0')
正确:if(*r=='\0')
【解析】
错误1:在经过“if”判断后执行后面括号内的语句时,每条语句应以“;”做结尾,“p++”后面没有分号即是错误。
错误2:该题目中定义*r为指针变量,r为指针名称,对其所指内容进行判断时应加“*”。
四、程序设计题(共24分)
请编一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M行N列的二维数组,求出二维数组每列中最大元素,并依次放入pp所指的一维数组中。二维数组中的数已在主函数中给出。
注意:
请勿改动主函数main和其他函数中的任何内容,仅在函数fun的花括号中填入你编写的若干语句。
【试题源程序】
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#define M 3
#define N 4
void fun(int tt[M][N],int pp[N])
{
}
void main()
{
int t[M][N]={{68,32,54,12},{14,24,88,58},{42,22,44,56}};
int p[N],i,j,k;
system("CLS");
printf("The riginal data is:\n");
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)printf("%6d",t[i][j]);
printf("\n");
}
fun(t,p);
printf("\nThe result is:\n");
for(k=0;k<N;k++)printf("%4d",p[k]);
printf("\n");
}
答:
void fun(int tt[M][N],int pp[N])
{
int i,j,max;
if(tt==NULL||pp==NULL)return;
for(j=0;j<N;j++)
{
max=tt[0][j];/*假设各列中的第一个元素最大*/
for(i=1;i<M;i++)if(tt[i][j]>max)max=tt[i][j];/*如果各列中的其他元素比最大值大,则将这个更大的元素看作当前该列中最大元素*/
pp[j]=max;/*将各列的最大值依次放入pp数组中*/
}
}
【解析】根据题意可知,fun函数实现的功能是对给定二维数组中每列的元素进行比较,得出最大值后依次输出至一维数组中。设计思路如下:定义一个最大值变量max,首先将每列的第一个元素设为最大值,然后将最大值max与第二个元素比较,较大值赋给max;以此类推,将max依次与第三,…,M个元素比较,得出该列最大值,并进行输出。