2016年3月全国计算机等级考试《二级C语言程序设计》真题及详解
(考试时间120分钟 满分100分)
一、选择题(每题1分,共40分)
1有以下定义:
struct data
{int i;char c;double d;}x;
以下叙述中错误的是( )。
A.x的内存地址与x.i的内存地址相同
B.struct data是一个类型名
C.初始化时,可以对x的所有成员同时赋初值
D.成员i、c和d占用的是同一个存储空间
【答案】D
【解析】变量i、c、d是结构体变量x中三个不同的成员,占用不同的存储空间。答案选择D选项。补充:区分struct和union,union的各个数据成员共享一块存储空间,struct不同的成员,占用不同的存储空间。
2以下函数的功能是:计算a的n次方作为函数值返回。
double fun(double a,int n)
{
int i;
double s=1.0;
for(i=1;i<=n;i++)s=______;
return s;
}
为实现上述功能,函数中下划线处应填入的是( )。
A.s*i
B.s*a
C.s+i*i
D.s+a*a
【答案】B
【解析】s为a的i-1次方的结果,所以令s=s*a即可得到a的i次方。答案选择B选项。
3有以下程序:
#include<stdio.h>
#include<string.h>
main()
{
char str[]={"Hello,Beijing"};
printf("%d,%d\n",strlen(str),sizeof(str));
}
程序的运行结果是( )。
A.13,13
B.13,14
C.13,15
D.14,15
【答案】B
【解析】strlen返回字符串的长度,不包含字符串末尾的结束字符'\0',结果为13;sizeof返回字符串所占存储空间的大小,由于字符串最后要加上一个'\0',所以结果为13+1=14。答案选择B选项。
4若有说明:typedef struct{int a;char c;}w;,则以下叙述正确的是( )。
A.编译后系统为w分配5个字节
B.编译后系统为w分配6个字节
C.编译后系统为w分配8个字节
D.编译后系统不为w分配存储空间
【答案】D
【解析】w是一个自定义类型,不是变量,故编译后系统不为w分配存储空间。当w定义为结构体变量时才会为其分配存储空间。答案选择D选项。
5以下叙述中错误的是( )。
A.同一个数组中所有元素的类型相同
B.不可以跳过前面的数组元素,给后面的元素赋初值0
C.定义语句:int a[10]={0};,给a数组中所有元素赋初值0
D.若有定义语句:int a[4]={1,2,3,4,5};,编译时将忽略多余的初值
【答案】D
【解析】数组初始化时,若赋初值的个数多于所定义数组的元素个数时,编译器会报错。答案选择D选项。
6若有以下定义:
struct tt{char name[10];char sex;}aa={"aaaa",'F'},*p=&aa;
则错误的语句是( )。
A.scanf("%c",aa.sex);
B.aa.sex=getchar();
C.printf("%c\n",(*p).sex);
D.printf("%c\n",p->sex);
【答案】A
【解析】sex是一个char类型变量,不是地址,A项应为scanf("%c",&aa.sex);。答案选择A选项。
7C语言编译程序的功能是( )。
A.执行一个C语言编写的源程序
B.把C源程序翻译成ASCII码
C.把C源程序翻译成机器代码
D.把C源程序与系统提供的库函数组合成一个二进制执行文件
【答案】C
【解析】编译程序的功能是将“高级语言”翻译为“机器语言”。每条C语言语句,经过编译最终都将转换成二进制的机器指令。答案选择C选项。
8有以下程序:
#include<stdio.h>
int fun(int n)
{
if(n) return fun(n-1)+n;
else return 0;
}
main()
{
printf("%d\n",fun(3));
}
程序的运行结果是( )。
A.4
B.5
C.6
D.7
【答案】C
【解析】fun函数是一个递归函数,调用f(3),参数n=3,返回f(3-1)+3=f(2)+3=f(1)+2+3=f(0)+1+2+3=0+6=6。答案选择C选项。
9有以下程序:
#include<stdio.h>
main()
{
int sum=0,x=5;
do{sum+=x;}while(!--x);
printf("%d\n",sum);
}
程序的运行结果是( )。
A.0
B.5
C.14
D.15
【答案】B
【解析】do-while循环,先执行循环体sum+=x,则sum=sum+x=0+5=5,再执行while中的表达式,结果为0,退出循环,所以运行结果是5。答案选择B选项。
10下面不属于软件设计阶段任务的是( )。
A.软件的功能确定
B.软件的总体结构设计
C.软件的数据设计
D.软件的过程设计
【答案】A
【解析】软件设计阶段的任务包括:①结构设计;②数据设计;③接口设计;④过程设计。软件的功能确定是在需求分析阶段完成的。答案选择A选项。
11有以下程序:
#include<stdio.h>
#include<string.h>
typedef struct{char name[9];char sex;float score[2];}STU;
void f(STU*a)
{
strcpy(a->name,"Zhao");
a->sex='m';
a->score[1]=90.0;
}
main()
{
STU c={"Qian",'f',95.0,92.0},*d=&c;
f(d);
printf("%s,%c,%2.0f,%2.0f\n",d->name,c.sex,c.score[0],c.score[1]);
}
程序的运行结果是( )。
A.Qian,f,95,92
B.Zhao,f,95,90
C.Zhao,m,95,90
D.Zhao,f,95,92
【答案】C
【解析】f函数调用时,结构体数组名作为实参传给形参指针,结构体指针a指向数组c的首地址。因此,f可以对数组c中的元素赋值,故返回主函数之后,数组c中的成员值已被更新。main函数中有赋值语句“*d=&c;”,指针d指向结构体数组c的首地址,故d->name=c.name,输出结果为Zhao,m,95,90。答案选择C选项。
12在C语言程序中,下列说法正确的是( )。
A.函数的定义可以嵌套,但函数的调用不可以嵌套
B.函数的定义不可以嵌套,但函数的调用可以嵌套
C.函数的定义和调用均不可以嵌套
D.函数的定义和调用均可以嵌套
【答案】B
【解析】函数定义都是在函数外部进行的,函数调用是在函数内部进行的,所以函数的定义不可以嵌套,但函数的调用可以嵌套(如递归函数)。答案选择B选项。
13执行以下程序段后,s的值为( )。
int a[]={1,2,3,4,5,6,7,8,9},s=0,k;
for(k=0;k<8;k+=2)s+=*(a+k);
A.13
B.16
C.17
D.45
【答案】B
【解析】获取数组a中第i个元素时,有两种形式:一是a[i],二是*(a+i)数组a中的元素为:a[0]=1,a[1]=2,…,a[8]=9。k=0时,s=s+*(a+0)=0+1=1;k=2时,s=1+*(a+2)=1+3=4;k=4时,s=4+5=9;k=6时,s=9+7=16。答案选择B选项。
14有以下程序:
#include<stdio.h>
#define M 5
#define f(x,y) x*y+M
main()
{
int k;
k=f(2,3)*f(2,3);
printf("%d\n",k);
}
程序的运行结果是( )。
A.22
B.41
C.100
D.121
【答案】B
【解析】宏定义中的函数在调用时只做简单的替换,不能进行任何修改。所以k=2*3+5*2*3+5=41。答案选择B选项。
15有以下程序:
#include<stdio.h>
main()
{
char ch='Z';
ch=(ch-'A'+1)%26+'A';
putchar(ch);
}
程序的运行结果是( )。
A.Z
B.Y
C.B
D.A
【答案】D
【解析】'Z'的ASCII码是90,'A'的ASCII码是65,所以ch=(ch-'A'+1)%26+'A'=26%26+65=65,输出65对应的字符'A'。答案选择D选项。
16下面属于黑盒测试方法的是( )。
A.基本路径测试
B.等价类划分
C.判定覆盖测试
D.语句覆盖测试
【答案】B
【解析】常用的黑盒测试方法有:①等价类划分法;②边界值分析法;③错误推测法;④因果图等。常用的白盒测方法有:①逻辑覆盖测试,包括语句覆盖、路径覆盖、判断覆盖、条件覆盖;②基本路径测试等,ACD三项属于白盒测试。答案选择B选项。
17有以下程序:
#include<stdio.h>
main()
{
int i,j,k,a=5,b=6;
i=(a==b)?++a:--b;
j=a++;
k=b;
printf("%d,%d,%d\n",i,j,k);
}
程序的运行结果是( )。
A.7,6,5
B.5,5,5
C.7,5,5
D.5,6,5
【答案】B
【解析】条件表达式i=(a==b)?++a:--b;中先执行a==b,值为假,根据三元运算符语法规则,执行--b,此时b为5,赋给i,i=5。j=a++,将a=5先赋给j,再进行a++,j=5,a=6,k=b=5,故最后输出的是5,5,5。答案选择B选项。
18C语言程序中,若函数无返回值,则应该对函数说明的类型是( )。
A.int
B.double
C.char
D.void
【答案】D
【解析】A项,int表示返回值是整型;B项,double表示返回值是双精度型;C项,char表示返回值是字符型;D项,void表示无返回值。答案选择D选项。
19有以下程序:
#include <stdio.h>
main()
{
int k,n=0;char c,str[]="teach";
for(k=0;str[k];k++)
{
c=str[k];
switch(k)
{
case 1:case 3:case 5:putchar(c);printf("%d",++n);break;
default:putchar('N');
}
}
}
程序的运行结果是( )。
A.Ne1NN
B.e1a2e3
C.Ne1Nc2N
D.Na1NNNN
【答案】C
【解析】程序执行过程:k=0时,c=str[0]='t',执行default分支,输出N;k=1时,c='e',执行case 1分支,没有break语句,继续执行case 3分支,没有break语句,继续执行case 5分支,输出e1;k=2时,c='a',输出N;k=3,c='c',输出c2;k=4,c='h',输出N。故程序的输出结果为Ne1Nc2N。答案选择C选项。
20有以下程序:
#include<stdio.h>
void fun(char(*p)[6])
{
int i;
for(i=0;i<4;i++)printf("%c",p[i][i]);
printf("\n");
}
main( )
{
char s[6][6]={"ABCDE","abcde","12345","FGHIJ","fghij","54321"};
fun(s);
}
程序的运行结果是( )。
A.Aa1F
B.Ab3I
C.ABCD
D.fghij
【答案】B
【解析】函数fun的功能是输出s[i][i],二维数组的对角线元素,所以程序会输出s[0][0]、s[1][1]、s[2][2]、s[3][3],即Ab3I。答案选择B选项。
21设变量x为long int型并已正确赋值,以下表达式中能将x的百位上的数字提取出的是( )。
A.x/10%100
B.x%10/100
C.x%100/10
D.x/100%10
【答案】D
【解析】x/100的个位数是x的百位数上的数字,所以再进行除10取余运算即可得到该数字。答案选择D选项。
22在E-R图中,用来表示实体的图形是( )。
A.椭圆形
B.矩形
C.菱形
D.三角形
【答案】B
【解析】E-R图是实体联系模式图,E-R图的三要素:①实体,用矩形框表示,框内为实体名称;②属性,用椭圆形表示,并用线与实体连接;③实体间的联系,用菱形框表示,用线将菱形框与实体相连,并在线上标注联系的类型。答案选择B选项。
23下面对软件特点描述不正确的是( )。
A.软件是一种逻辑实体,具有抽象性
B.软件开发、运行对计算机系统具有依赖性
C.软件开发涉及软件知识产权、法律及心理等社会因素
D.软件运行存在磨损和老化问题
【答案】D
【解析】软件具有以下特点:①软件具有抽象性,是一种逻辑实体;②软件没有明显的制作过程;③软件在使用期间不存在磨损、老化问题;④对硬件和环境具有依赖性;⑤软件复杂性高,成本昂贵;⑥软件开发涉及诸多的社会因素。D项描述是硬件存在的问题。答案选择D选项。
24.设x,y,z均为实型变量,代数式在C语言中的正确写法是( )。
A.x/y*z
B.x%y%z
C.x/y/z
D.x*z/y
【答案】C
【解析】%是取余运算符,不符合。运算符*、/的结合顺序是从左到右,所以x先除以y,再除以z。答案选择C选项。
25有以下程序:
#include<stdio.h>
#define N 4
void fun(int a[ ][N],int b[ ])
{
int i;
for(i=0;i<N;i++)b[i]=a[i][N-1-i];
}
main()
{
int x[N][N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},y[N],i;
fun(x,y);
for(i=0;i<N;i++)printf("%d,",y[i]);
printf("\n");
}
程序的运行结果是( )。
A.1,2,3,4,
B.3,6,9,12,
C.4,7,10,13,
D.1,5,9,13,
【答案】C
【解析】函数fun的功能是将参数a的二维数组中反斜对角对应的数依次赋值给参数b的一维数组。调用fun函数,y[i]=x[i][N-1-i],N=4,x是4行4列的二维数组。i=0时,y[0]=x[0][4-1]=x[0][3]=4;i=1时,y[1]=x[1][4-1-1]=x[1][2]=7;i=2时,y[2]=x[2][4-1-2]=x[2][1]=10;i=3时,y[3]=x[3][0]=13。答案选择C选项。
26在下列链表中,能够从任意一个结点出发直接访问到所有结点的是( )。
A.单链表
B.循环链表
C.双向链表
D.二叉链表
【答案】B
【解析】对于线性单链表来说,每个结点只有一个指针域,这个指针只能找到其后继结点,但不能找到其前驱结点,因此必须从头指针开始,才能访问到所有的结点;循环链表的最后一个结点的指针域指向表头结点,所有结点的指针构成了一个环状链,只要指出表中任何一个结点的位置就可以从它出发访问到表中其他所有的结点;题目要求是“直接”,如果是双向链表的话,从中间一个点开始,必须先往左一次再掉头往右一次才能遍历。而循环链表只要沿一个方向一直走下去就可以遍历;二叉链表是二叉树的一种链式存储结构,每个结点有两个指针域,分别指向左右子结点,可见,二叉链表只能由根结点向叶子结点的方向遍历,其他部分的结点无法访问。答案选择B选项。
27有以下程序:
#include<stdio.h>
main()
{
int i,j,x=0;
for(i=0;i<2;i++)
{
x++;
for(j=0;j<=3;j++)
{
if(j%2==0)continue;
x++;
}
x++;
}
printf("x=%d\n",x);
}
程序的运行结果是( )。
A.x=4
B.x=6
C.x=8
D.x=12
【答案】C
【解析】第一次循环:i=0,执行x++后x=1,执行内层循环j=0,由于j%2!=0时才执行x++,即只有j取1和3时,执行x++,此时x=1+1+1=3,跳出内层循环,执行下一条x++,x=4,第二次循环:x=1时,重复上述循环,共执行两次循环,故x最终结果是4*2=8。答案选择C选项。注意,在循环体中遇到continue,则跳过continue后的语句直接进入下一次循环的判断。
28对图书进行编目时,图书有如下属性:ISBN书号,书名,作者,出版社,出版日期。能作为关键字的是( )。
A.ISBN书号
B.书名
C.作者,出版社
D.出版社,出版日期
【答案】A
【解析】关键字是指能惟一标识元组的属性或属性集合。书号可以惟一标识一本图书,本题中,书名、作者、出版社、出版日期等字段都不能惟一标识一本图书。答案选择A选项。
29若主函数中有定义语句:int a[10],b[10],c;,在主函数前定义的fun函数首部为:void fun(int x[]),则以下选项中错误的调用语句是( )。
A.fun(b);
B.fun(&c);
C.fun(&a[3]);
D.fun(b[11]);
【答案】D
【解析】fun函数的形式参数为一个数组,需要实参为一个地址,而b[11]是一个整型元素,参数类型不一致,且b[11]已经溢出,所以D项错误。
30构成C语言程序的三种基本结构是( )。
A.顺序结构、转移结构、递归结构
B.顺序结构、嵌套结构、递归结构
C.顺序结构、选择结构、循环结构
D.选择结构、循环结构、嵌套结构
【答案】C
【解析】C语言程序是结构化程序,由三种基本结构组成:①顺序结构;②选择结构;③循环结构。答案选择C选项。
31下列形式中不合法的常量是( )。
A.2.E8
B.-.28
C.-028
D.2e-8
【答案】C
【解析】-028表示的是八进制的整型常量,但八进制的数字只能用0~7表示。AD两项为指数形式的实数表示,在e或E的前面必须要有数字,且e或E后面的指数必须为整数;B项,为整数常量。答案选择C选项。
32下列与栈结构有关联的是( )。
A.数组的定义域使用
B.操作系统的进程调度
C.函数的递归调用
D.选择结构的执行
【答案】C
【解析】函数的递归调用是指函数调用函数本身,直到满足特定条件时终止,然后从最后被递归调用处返回。递归函数是通过栈来实现的,所以调用原则和栈的实现相一致。所以递归函数是通过栈来实现的。答案选择C选项。
33以下不是C语言字符型或字符串常量的是( )。
A."It’s"
B."0"
C.'a=0'
D.'\010'
【答案】C
【解析】字符常量是用单引号把一个字符括起来,转义字符常量以一个反斜线开头后跟一个特定的字符或者对应的ASCII值表示。字符串常量是由双引号括起来的一串字符。C项既不是字符型常量,也不是字符串常量。AB两项,均是字符串常量;D项,是字符型常量。答案选择C选项。
34下列数据结构中,属于非线性结构的是( )。
A.双向链表
B.循环链表
C.二叉链表
D.循环队列
【答案】C
【解析】线性结构要满足两个条件:①有且仅有一个根结点;②每个结点最多有一个前驱,也最多有一个后继。线性表、栈、队列都是线性结构,循环链表和双向链表是线性表的链式存储结构,属于线性结构,只是存储结构不连续;循环队列是一个头结点和尾结点互为前驱结点和后继结点的特殊的队列,属于线性结构;二叉链表是二叉树的链式存储结构,因为二叉树有些结点有两个后继结点,不符合线性结构的定义,所以二叉链表是非线性结构。答案选择C选项。
35有以下程序:
#include<stdio.h>
main()
{
int k=10;
printf("%4d,%o,%x\n",k,k,k);
}
程序的运行结果是( )。(u代表一个空格)
A.10,12,a
B.uu10,012,a
C.010,12,a
D.uu10,12,a
【答案】D
【解析】%4d表示输出占4个字符的十进制,故先输出2个空格,然后输出10;%o表示输出八进制,所以输出10的八进制为12;%x表示输出十六进制,即a。答案选择D选项。
36数据库管理系统是( )。
A.操作系统的一部分
B.系统软件
C.一种编译系统
D.一种通信软件系统
【答案】B
【解析】系统软件主要包括:①操作系统软件;②各种语言的解释程序和编译程序;③各种服务性程序;④各种数据库管理系统。数据库管理系统是一种系统软件,负责数据库中的数据组织、数组操纵、数据维护、控制和保护以及数据服务等。答案选择B选项。
37若有定义:int a=1,b=2,c=3;,则执行表达式(a=b+c)||(++b)后,a、b、c的值依次为( )。
A.1,2,3
B.5,3,2
C.5,2,3
D.5,3,3
【答案】C
【解析】||表示或运算,当第一个表达式为真时,第二个表达式不执行。根据运算符的优先级规则,先计算(a=b+c),将b+c的值赋值给a,则a=5,而||右边的括号不会被执行,所以b=2,c=3。答案选择C选项。
38有两个关系R和T如下:
则由关系R得到关系T的操作是( )。
A.选择
B.交
C.投影
D.并
【答案】C
【解析】关系T是由关系R的第1、3列的元组组成,这是对关系R进行投影运算的结果。可以简单理解为:选择运算是对行(元组)的操作,投影运算是对列的操作。投影是从表中选出指定的属性值组成新表,是单目运算,C项正确。
39设有:char s[5],c;,则调用函数scanf能正确给s和c读入数据的是( )。
A.scanf("%s%c",s,c);
B.scanf("%d%c",&s,&c);
C.scanf("%d%c",s,&c);
D.scanf("%s%c",s,&c);
【答案】D
【解析】s[5]是一个字符数组,也可以理解为字符串,格式控制为%s,c为字符,格式控制为%c。scanf输入时参数是地址,数组名就是地址,所以给s读入数据参数就是s首地址,而字符c的参数需要取c的地址,即&c。答案选择D选项。
40若变量已正确定义并赋值,则错误的赋值语句是( )。
A.a+=a+1;
B.a=sizeof(double);
C.a=d||c;
D.a+1=a;
【答案】D
【解析】赋值号的左边必须是一个代表某个存储单元的变量名,赋值号的右边必须是C语言中合法的表达式。赋值运算的功能是先求出右边表达式的值,然后把此值赋给赋值号左边的变量。答案选择D选项。
二、程序填空题(共18分)
下列给定的程序中,函数fun()的功能是:求出以下分数序列的前n项和。2/1,3/2,5/3,8/5,13/8,21/13,……和值通过函数值返回main()函数。例如,若输入n=5,则应输出8.391667。
注意:
请勿改动主函数main和其他函数中的任何内容,仅在函数fun的横线上填入所编写的若干表达式或语句。
【试题源程序】
#include<stdio.h>
#include<conio.h>
double fun(int n)
{
int a=2,b=1,c,k;
double ①______;
for(k=1;k<=n;k++)
{
s=s+1.0*a/b;
c=a;a+=②______;b=c;
}
return(s);
}
main()
{
int n=5;
printf("\nThe value of function is:%1f\n",③______);
}
答:
①s=0.0
②b
③fun(n)
【解析】
填空1:此处要对变量s进行声明,因为后面有对s的累加操作,所以s一定要进行初始化,即s=0.0。
填空2:此处是循环求和,由数列可以看出后一项分数的分子是前一项分母与分子之和,即a=a+b或者a+=b。
填空3:此处进行子函数调用。
三、程序修改题(共18分)
给定程序中函数fun的功能是:根据整型形参m,计算如下公式的值。
例如,若m中的值为:5,则应输出:1.463611。请改正程序中的错误,使它能得到正确结果。
注意:
不要改动main函数,不得增行或删行,也不得更改程序的结构。
【试题源程序】
#include<stdio.h>
double fun(int m)
{
double y=1.0;
int i;
/**********found**********/
for(i=2;i<m;i++)
/**********found**********/
y+=1/(i*i);
return(y);
}
main()
{
int n=5;
printf("\nThe result is %1f\n",fun(n));
}
答:
(1)错误:for(i=2;i<m;i++)
正确:for(i=2;i<=m;i++)
(2)错误:y+=1/(i*i)
正确:y+=1.0/(i*i)
【解析】
错误1:使用for循环计算公式取到m时,最后一次循环应该等于m,所以i小于m应改为i小于等于m。
错误2:在除法运算中,如果除数和被除数都是整数,那么所除结果也是整数,因此需要对结果进行强制转换或者将除数或被除数其中一个整型常量变为浮点型常量。
四、程序设计题(共24分)
请编写函数fun(),该函数的功能是:移动一维数组中的内容,若数组中有n个整数,要求把下标从p~n-1(p<n-1)的数组元素平移到数组的前面。
例如,一维数组中的原始内容为1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,p的值为6。移动后,一维数组的内容应为7,8,9,10,11,12,13,14,15,1,2,3,4,5,6。
注意:
请勿改动主函数main和其他函数中的任何内容,仅在函数fun的花括号中填入所编写的若干语句。
【试题源程序】
#include<stdio.h>
#define N 80
void fun(int *w,int p,int n)
{
}
main()
{
int a[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int i,p,n=15;
printf("The original data:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
printf("\n\nEnter p:");
scanf("%d",&p);
fun(a,p,n);
printf("\nThe data after moving:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
printf("\n\n");
}
答:
void fun(int*w,int p,int n)
{
int i,j,t;
for(i=p;i<=n-1;i++)
{
t=w[n-1];
for(j=n-2;j>=0;j--)
w[j+1]=w[j];
w[0]=t;
}
}
【解析】本题采用“循环右移”的算法。