1.1 公共基础
1.计算机中的缓冲技术用于( )
(A)提供主、辅存接口 | (B)提高主机和设备交换信息的速度 |
(C)提高设备利用率 | (D)扩充相对地址空间 |
【解析】缓冲技术是为了协调吞吐速度相差很大的设备之间数据传送而采用的技术
【答案】(B)
1.1.1 数据库
3.下面模型中为概念模型的是( )。
(A)层次模型 | (B)关系模型 | (C)网状模型 | (D)实体-联系模型 |
【解析】
【答案】(D)
1.1.2 数据结构
1.下列叙述中错误的是( )
(A)循环队列空的条件是队头指针与队尾指针相同 |
(B)若二叉树没有叶子结点,则为空二叉树 |
(C)带链栈的栈底指针是随栈的操作而动态变化的 |
(D)若带链队列中只有一个元素,则队头指针与队尾指针必定相同 |
【答案】(A)
1.1.3 数据结构与存储结构
1.下列叙述中正确的是( )
(A)顺序存储结构只能表示线性结构 |
(B)循环队列与循环链表都是线性结构 |
(C)具有多个指针域的链表肯定是非线性结构 |
(D)双向链表既能表示线性结构,又能表示非线性结构 |
【解析】二叉树属于非线性结构,但满二叉树与完全二叉树可以按层次进行顺序存储,(A)错误。双向链表虽然有两个指针域,但一前一后的关系没有改变,因此只能表示线性结构。
【答案】(B)
2.下列数据结构中,不能采用顺序存储结构的是( )
(A)堆 | (B)队列 | (C)栈 | (D)非完全二叉树 |
【解析】堆只是一种结点数据关系特殊的二叉树,但在节点结构上是按照完全二叉树进行分布的,可以按层次进行顺序存储。
【答案】(D)
3.下列叙述中正确的是( )
(A)双向链表有两个头指针 | (B)双向链表有两个头结点 |
(C)循环链表中至少有一个结点 | (D)循环链表是循环队列的链式存储结构 |
【答案】(C)
4.下列叙述中正确的是( )。
(A)有一个以上根节点的数据结构不一定是非线性结构 |
(B)只有一个根节点的数据结构不一定是线性结构 |
(C)循环链表是非线性结构 |
(D)双向链表是非线性结构 |
【答案】(B)
5.下列叙述中错误的是( )
(A)栈是线性结构 | (B)二叉链表是二叉树的存储结构 |
(C)循环链表是循环队列的存储结构 | (D)循环队列是队列的存储结构 |
【解析】玩尼玛的绕口令
【答案】(C)
6.下列叙述中错误的是( )
(A)向量属于线性结构 | (B)二叉链表是二叉树的存储结构 |
(C)栈和队列是线性表 | (D)循环链表是循环队列的链式存储结构 |
【解析】
【答案】(D)
1.2 C语言
1.2.1 概念题
1.以下关于C语言的叙述中正确的是( )
(A)C语言的数值常量中夹带空格不影响常量值的正确表示 |
(B)C语言中的变量可以在使用之前的任何位置进行定义 |
(C)在C语言算术表达式的书写中,运算符两侧的运算数类型必须一致 |
(D)C语言中的注释不可以夹在变量名或关键字的中间 |
【解析】(B)确实要先定义后使用,但不能是任意位置,比如函数体内部还是外部就关系到这个变量是全局变量还是局部变量。 运算符两侧数据类型可以不一致,结果与精度较高的保持一致。
【答案】(D)
2.下列叙述中正确的是( )
(A)C程序中所有函数之间都可以相互调用 |
(B)在C程序中mian函数的位置是固定的 |
(C)在C程序的函数中不能定义另一个函数 |
(D)每个C程序文件中都必须要有一个main函数 |
【解析】主函数不能被其他函数调用,(A)错。每个C程序中必须包含一个main函数,但不一定是每个C程序文件中必须有。
【答案】(C)
3.关于C语言的变量,以下叙述中错误的是( )
(A)变量所占的存储单元地址可以随时改变 |
(B)所谓变量是指在程序运行过程中其值可以被改变的量 |
(C)程序中用到的所有变量都必须先定义后才能使用 |
(D)由三条下划线构成的符号名是合法的变量名 |
【解析】一个变量实质是代表了内存中的某个储存单元,必须先定义后使用,且在定义时为之分配存储单元,不能随时改变。
【答案】(A)
4.以下选项中不能在C语言程序中用作用户标识的是( )
(A)auto | (B)scanf | (C)Float | (D)_3_14 |
【解析】auto是C语言关键字,不能用作用户标识符。scanf是标准库函数名,可以用作用户标识符,只是使用标识符的地方不能包含stdio.h头文件。
【答案】(A)
1.2.2 二、八、十、十六进制负数
1.以下不属于C语言整型常量的是( )
(A)0L | (B)-018 | (C)0Xa | (D)200U |
【解析】
【答案】(B)
1.2.1 字符数组初始化
字符数组初始化分两种字符形式和字符串形式:
(1)字符形式
一维字符数组,将字符串分解为字符,在字符数组中放入,这时可省略数组下标。
char c[5]={'c','h','i','n','a'};等价于char c[]={'c','h','i','n','a'};
(2)字符串形式
同样是一维字符数组,有两种方式进行字符串的初始化。第一种直接用字符串常量,没有花括号,不能省略下标:
char c[6]="china";
通过花括号时,可省略下标:
char c[]={"china"};
1.设有如下程序段
int a[2]={0};
int b[]={0,0,1};
char c[]={"A"};
char d="\0";
以下叙述中正确的是( )
(A)a、b的定义合法,c、d的定义不合法 | (B)所有定义都是合法的 |
(C)只有d的定义不合法,其余定义均合法 | (D)只有a的定义合法,其余定义均不合法 |
【答案】(C)
1.2.2 “\”是字符串合法表达式吗?
1.以下正确的字符串常量是( )
(A)"\\\" | (B)'abc' | (C)Olympic Games | (D)"" |
【解析】(A)选项中前两个(\\)代表了一个\字符,后面一个得和“一起(\")才被看作一个“,所以该字符串缺少一个结束的”,因此不正确。(D)选项的两个“之间没有任何字符,代表的是一个空串包括字符串结束标识符”\0“,所以是合法的字符串常量。
【答案】(D)
1.2.2 运算符
1.C语言程序中,运算对象必须是整型数的运算符是( )
(A)&& | (B)/ | (C)% | (D)* |
【解析】
【答案】(C)
1.2.3 逗号运算符和自增自减运算
C语言中,逗号运算符可以把两个以上(包含两个)的表达式连接成一个表达式,它的作用在于保证左边的子表达式运算结束后才进行右边的子表达式运算,并以最右边表达式值作为整个逗号表达式的值,且逗号运算符的优先级在所有运算符里最低。
1.若定义:double x;,则表达式:x=0,x+10,x++的值是( )
(A)11.0 | (B)10.0 | (C)0.0 | (D)1.0 |
【答案】(C)
1.2.2 字符串与字符数组的区别
1.以下叙述错误的是( )
(A)字符串和字符数组的差别是,在其所占空间里,前者一定存储了'\0',而后者不一定 |
(B)从内存某个地址开始按字节向后,直至某字节的值为’\0‘,这就是一个字符串 |
(C)字符串指的是内存中连续存储的英文字母或数字字符 |
(D)指向字符串的指针与指向字符数组的指针的类型是一样的,都是char * |
【答案】(C)
1.2.1 当转义字符出现\0xx时,其表示的是结束标识符\0和数字字符xx,还是3位八进制表示的ASCII码呢?
优先表示为3位八进制。
1.语句
printf("%d\n",strlen("\t\"\\\n\'\065\08AB"));
的输出结果是( )
(A)6 | (B)7 | (C)8 | (D)9 |
【解析】
【答案】(A)
2.有以下程序段
char *s="\t\007\0a\n";
for(;*s;s++)
printf("!");
(A)6 | (B)7 | (C)8 | (D)9 |
【答案】(C)
1.2.2 转义字符与pirnf()结合
1.有以下程序
#include <stdio.h>
main()
{
int a=2,c=5;
printf("a=%%d,b=%%d\n",a,c);
}
程序的输出结果是( )
(A)a=2,b=5 | (B)a=%2,b=%5 | (C)a=%d,b=%d | (D)a=%%d,b=%%d |
【解析】优先使用转义字符
【答案】(C)
1.2.2 判断语句
1.以下运用if语句判断x和y大小的程序段,错误的是( )
(A)if(x>y) printf("x>y"); if(x<y) printf("x<y"); else printf("x=y"); |
(B)if(x>=y) if(x>y) printf("x>y"); else printf("x=y"); else printf("x<y"); |
(C)if(x>y) printf("x>y"); if(y>x) printf("x<y"); if(x==y) printf("x=y"); |
(D)if(x>y) printf("x>y"); else if(x<y) printf("x<y"); else printf("x=y"); |
【解析】选项A中,当x>y时,执行printf("x>y"),接着判断if(x<y)为false,执行printf("x=y")
【答案】(A)
1.2.2 函数声明
1.设有某函数的说明为:
int* func(int a[10],int n);
则下列叙述中,正确的是( )。
(A)形参a对应的实参只能是数组名 |
(B)说明中的a[10]写成a[]或*a效果完全一样 |
(C)func的函数体中不能对a进行移动指针(如a++)的操作 |
(D)只有指向10个整数内存单元的指针,才能作为实参传给a |
【解析】首先,由于有”;“,所以这是一条函数的声明语句,不是定义。函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型等,它是一个完整的独立的函数单位。声明是指利用它在程序的编译阶段对调用函数的合法性进行全面检查,它把函数的名字、函数类型、形参个数、形参类型等通知给编译系统,以便在调用该函数时系统按此声明进行对照检查。
(1)函数声明中参数名可省略,也可以是任意合法的用户标识符,不必与函数定义中的形参名一致,甚至还能与程序中其它用户标识符同名。
【答案】(B)
2.对于函数声明
void fun(int a[1],int *b);
以下叙述中正确的是( )
(A)函数参数a、b都是指针变量 |
(B)声明有语法错误,参数a的数组大小必须大于1 |
(C)调用该函数时,形参a仅复制实参数组中第一个元素 |
(D)调用该函数时,a的值是对应实参数组的内容,b的值是对应实参的地址 |
【答案】(A)
3.对于函数声明:
void(float array[ ],int *ptr);
以下叙述中正确的是( )。
(A)调用函数时,array数组的元素和ptr都是按值传送 |
(B)函数声明有语法错误,参数array缺少数组大小的定义 |
(C)调用函数时,array数组中将存储从实参中复制来的元素值 |
(D)函数参数array,ptr都是指针变量 |
【答案】(D)
3.若有如下形式的函数
int fun(int a[], int *p, int n)
{……}
调用函数之前需要对函数进行声明,则以下选项中错误的是( )
(A)int fun(int, int, int); | (B)int fun(int a[], int *p, int n); |
(C)int fun(int a[], int *, int); | (D)int fun(int [], int *, int); |
【解析】尽管函数声明中形参的名字无所谓,但数据类型与函数形参一致
【答案】(A)
4.若各选中所用变量已正确定义,函数fun中通过return语句返回一个函数值,以下选项中错误的程序是( )
(A)main() {…… x=fun(2,10); ……} float fun(int a,int b){……} |
(B)float fun(int a,int b){……} main() {…… x=fun(i,j); ……} |
(C)float fun(int, int); main() {…… x=fun(2,10); ……} |
(D)main() {float fun(int i, int j); …… x=fun(i,j); ……} |
【解析】(A)选项,调用时,没有对子函数进行说明。(B)、(C)选项中被调用函数在主调函数之前定义,不用说明;(D)选项中在主函数中对被调用函数的返回值类型进行了说明。
【答案】(A)
1.2.3 使用strlen()计算字符串含有转义字符形式的字符串
转义字符形式为进制的,不能将其转变为十进制进行长度计算,而是保持原本的形式作为字符。而转义字符形式为“\”则要将其转换后再计算长度。
1.有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char* str="0\n0123\4";
printf("%d",strlen(str));
}
程序运行后的输出结果是( )
(A)3 | (B)6 | (C)8 | (D)7 |
【答案】(D)
1.2.4 使用sizeof()计算字符数组名和指针
使用sizeof()计算字符数组名时,分为两种情况:
(1)当字符数组定义时有维度,计算的是整个字符数组所占空间的字节数,而不仅仅只是字符串的大小;
(2)字符数组定义时没有维度,且字符串中有“\0”,那么数组大小是初始化的字符个数,即要分别计算“\”和“0”。
计算指针时,无论基类型是什么,结果都是4个字节。
1.有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char a[4]="23",*b="10\0";
printf("%d\n",strlen(a)+sizeof(a)+strlen(b)+sizeof(b));
}
程序运行后的输出结果是( )
(A)17 | (B)15 | (C)12 | (D)18 |
【答案】(C)
2.有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char a[5]="123",*b="0\0";
printf("%d\n",sizeof(a)+strlen(b));
}
(A)8 | (B)7 | (C)4 | (D)6 |
【答案】(D)
3.有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char a[]="THIS\0",*b="OK\0\0";
printf("%d,%d,%d,%d",strlen(a),sizeof(a),strlen(b),sizeof(b));
}
程序运行后的输出结果是( )
(A)4,6,2,4 | (B)4,4,4,1 | (C)6,5,2,1 | (D)6,4,2,4 |
【解析】
【答案】(A)
1.2.4 if()……else()没有花括号在for循环中如何执行
1.有以下程序
#include <stdio.h>
main()
{
char c;
while(c=getchar())
{
if(c=='i')
{
c=getchar();
for(;!((c=='i')||(c=='.')||(c=='\n')); c=getchar())
if(c=='a')
continue;
else
printf("%c",c);
}
else if(c=='\n')
break;
}
printf("%c",c);
}
若程序运行时输入字符串:this is a string.<回车>,则程序的运行结果是( )
(A)s ng | (B)s s ng | (C)s s strng | (D)sng |
【解析】即便没有花括号,由于else与最近的一个未配对的if配对,所以else并不会单独隔开。
【答案】(A)
1.2.1 省略函数返回值类型时,使用return
1.若函数fun定义如下
fun(void)
{
double d;
long t=rand();
d=t*0.618;
return d;
}
则函数返回值的类型是( )
(A)void | (B)double | (C)int | (D)long |
【解析】当函数的返回类型为int类型时,可以省略函数的返回类型
【答案】(C)
1.2.2 指针
1.以下程序段完全正确的是( )
(A)int *p; scanf("%d",&p) | (B)int *p; scanf("%d",p); |
(C)int k,*p=&k; scanf("%d",p); | (D)int k,*p; *p=&k; scanf("%d",p); |
【解析】(B)中对指针没有初始化,无效指针。
【答案】(C)
2.关于数组和指针,以下说法错误的是( )
(A)数组名本身就是一个指针,指向数组内存的起始位置 |
(B)既可以读入数据到数组中,也可以读入数据到未赋初值的指针中 |
(C)可以让一个指针指向一个同类型的数组 |
(D)指针可以指向同类型的数组中的任意一个元素 |
【解析】已经定义的数组被分配了内存空间,所以可以读入数据到数组中,未赋初值的指针没有分配内存空间,所以不可以读入数据。
【答案】(B)
1.2.5 基类型为void的指针转换问题
1.有以下程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void fun1(char *);
void fun2(double *);
main()
{
void *p;
p=malloc(8);
fun1((char *)p);
fun2((double *)p);
printf("%s\n",(char *)p);
}
void fun1(char *p)
{ strcpy(p,"Hello");
}
void fun2(double *p)
{
char *p;
q=(char *)p;
strcpy(q,"World");
}
程序运行的结果是( )
(A)Hello World | (B)Hello | (C)World | (D)World Hello |
【解析】
【答案】(C)
1.2.2 循环条件判断涉及到局部变量的作用域
1.有以下程序
#include <stdio.h>
int a[5]={7,10,3};
int n=3;
int *p=a;
void main()
{
int i;
int a[2]={1,0};
for(i=0;a[i];i++)
printf("%4d",a[i]);
for(i=0;a[i];i++)
{
int a[3]={100,200,300};
printf("%4d",a[i]);
}
printf("\n");
}
程序的运行结果是( )
(A)1 100 | (B)1 0 100 200 300 | (C)1 100 200 300 | (D)1 100 200 |
【解析】第二个for循环中a[3]数组的作用域仅限于for循环内部,当对循环条件进行判断时,依据的是a[2]数组中的元素。
【答案】(A)
5.2.8 循环、switch、break和continue的相互组合
总结:当循环体内嵌套了switch,并且switch内有break,那么执行break后打破的是switch。
1.有以下程序:
#include<stdio.h>
main()
{
int s;
scanf("%d",&s);
while(s>0)
{
switch(s>0)
{
case 1:
printf("%d",s+5);
case 2:
printf("%d",s+4);
break;
case 3:
printf("%d",s+3);
default:printf("%d",s+1);
break;
}
scanf("%d",&s);
}
}
运行时,若输入1 2 3 4 5 0<回车>,则输出结果是( )
(A)66656 | (B)6566456 | (C)66666 | (D)6666656 |
【解析】程序本身的难点在于,break打破的是switch还是循环。但从做题的角度来说,最开始一定是65,可以确定(B)选项。
【答案】(B)
2.若有以下程序
#include<stdio.h>
main()
{ int s=0,n;
for(n=0;n<4;n++)
{ switch(n)
{ default:s+=4;
case 1:s+=1; break;
case 2:s+=2; break;
case 3:s+=3;
}
}
printf("%d\n",s);
}
则程序的输出结果是( )
(A)10 | (B)11 | (C)13 | (D)15 |
【解析】从做题角度看,如果break打破的是for循环,那么s应该等于5,但没有这个选项,所以break打破的是switch。
【答案】(B)
3.若有以下程序
#include<stdio.h>
char *a="you";
char b[]="Welcome you to China!";
main()
{ int i,j=0;char *p;
for(i=0;b[i]!='\0';i++)
{ if(*a==b[i])
{ p=a;
for(j=i;*p!='\0';j++)
{ if(*p!=b[j]) break;
p++;
}
if(*p=='\0') break;
}
}
printf("%s",&b[i]);
}
则程序的输出结果是( )。
(A)China! | (B)to China! | (C)me you to China! | (D)you to China! |
【答案】(D)
4.有以下程序:
#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)continue;
x++;
}
x++;
}
printf("x=%d\n",x);
}
程序执行后的输出结果是( )
(A)x=4 | (B)x=8 | x=6 | (D)x=12 |
【答案】(B)
5.有以下程序:
#include<stdio.h>
main()
{
int x=8;
for( ;x>0;x--)
{
if(x%3)
{
printf("%d,",x--);
continue;
}
printf("%d,"--x);
}
}
程序的运行结果是( )
(A)7,4,2 | (B)8,7,5,2 | (C)9,7,6,4 | (D)8,5,4,2 |
【答案】(D)
6.有以下程序段:
#include <stdio.h>
void main(){
int i, n;
for(i = 0; i<8;i++)
{
n=rand()%5;
switch(n)
{case 1:
case 3:printf("%d \n", n);break;
case 2:
case 4:printf("%d \n", n);continue;
case 0:exit(0);
}
printf("%d \n", n);
}
}
以下关于程序段执行情况的叙述,正确的是( )
(A)for循环语句固定执行8次 | (B)当产生的随机数n为4时结束循环操作 |
(C)当产生的随机数n为1和2时不做任何操作 | (D)当产生的随机数n为0时结束程序运行 |
【解析】如果执行exit(0)会终止整个程序,所以(A)错。switch是选择语句,并不能使用continue语句,但是由于外部有个for循环,在for循环内部处可任意有continue语句。根据continue的作用可知,在某次循环时,n=4,会执行到continue,该次循环会立即结束,直接转入判断循环条件,循环并没有结束。随机数为1和2,不是不做任何操作,只是case 1和case 2的后面的操作为空≠不做任何操作。
【答案】(D)
1.2.3 extern外部变量声明的作用
#include <stdio.h>
void fun1();
void fun2(int a);
main()
{
extren int mdt;
printf("%c",mdt);
fun1();
printf("%c",mdt);
fun2();
printf("%c",mdt);
}
void fun1()
{
extern int mdt;
++mdt;
fun2(3);
}
int mdt='A';
void fun2(int a)
{
static int mdt='a';
mdt+=a;
printf("%d",a);
printf("%c",mdt);
}
程序运行的结果是( )
(A)A3DB2FB | (B)a3Db2Fb | (C)A3dB2fB | (D)a3db2fb |
【答案】(C)
1.2.6 结构体变量定义与typedef定义结合
1.有如下定义
typedef struct
{
int bookID;
double price;
}ND;
typedef ND NDA[100];
则以下叙述正确的是( )
(A)NDA是一个类型名,该类型的变量具有100个元素,每个元素的类型是结构体类型ND |
(B)NDA是一个数组名,它有100个元素,每个元素的类型是结构体类型ND |
(C)ND是一个类型名,该类型的变量具有100个元素,每个元素的类型是结构体类型ND |
(D)ND是一个数组名,它有100个元素,每个元素的类型是结构体类型ND |
【解析】
【答案】(A)
1.2.7 通过scanf()给结构体成员赋值
1.有以下结构体说明、变量定义和赋值语句:
struct STD
{
char name[10];
int age;
char sex;
}s[5],*ps;
ps=&s[0];
则以下scanf函数调用语句有错误的是( )。
(A)scanf("%s",s[0].name); | (B)scanf("%d",&s[0].age); |
(C)scanf("%c",&(ps->sex)); | (D)scanf("%d",ps->age); |
【解析】scanf()的参数要求是地址或者是指针,弄清楚谁是地址或指针,谁不是。ps是指向s[0]这个元素的指针,再通过结构指向运算符指向sex,其为s[0]结构体变量中的sex变量,再取地址“&”,(C)没有错误。同理,(B)。对于(A),name是一个数组名,但同时也是一个地址常量。
【答案】(D)
1.以下叙述中错误的是( )
(A)将函数内的局部变量说明为static存储类是为了限制其他编译单位的引用 |
(B)一个变量作用域的开始位置完全取决于变量定义语句的位置 |
(C)全局变量可以在函数以外的任何部位进行定义 |
(D)局部变量的“生存期”只限于本次函数调用,因此不能将局部变量的运算结果保存至下一次调用 |
【解析】
【答案】(A)
1.有以下程序
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void fun(int a[],char *b)
{
int i,len;
len=strlen(b);
for(i=0;i<len;i++)
a[i]+=tolower(b[i])-'a';
}
void mian()
{
int a[20]={1,2,3,4,5},i;
char s[]="aBcDe";
fun(a,s);
for(i=0;i<strlen(s);i++)
{
printf("%d",a[i]);
}
printf("\n");
}
程序运行后的输出结果是( )
(A)1 67 3 69 5 | (B)66 67 68 69 70 | (C)1 3 5 7 9 | (D)97 98 99 100 101 |
【答案】(C)
2.有以下程序
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void fun(char p[])
{
int len;
len=strlen(p);
while(*p)
{
if(isupper(*p))
tolower(*p);
else if(islower(*p))
toupper(*p);
else (*p)++;
p++;
}
}
void main()
{
char a[20]="Ab1Cd2eF3";
fun(a);
puts(a);
}
程序运行的结果是( )
(A)Ab1Cd2eF3 | (B)Ab2Cd3eF4 | (C)aB2cD3Ef4 | (D)aB1cD2Ef3 |
【解析】tolower()和toupper()和虽然返回了对应的小写和大写字母,但是没有赋值语句。
【答案】(B)
7.有以下程序
#include<stdio.h>
main()
{ FILE *fp;char str[10];
fp=fopen("myfile.dat","w");
fputs("abc",fp);
fclose(fp);
fp=fopen("myfile.dat","a+");
fprintf(fp,"%d",28);
rewind(fp);
fscanf(fp,"%s",str);
puts(str);
fclose(fp);
}
程序运行后的输出结果是( )。
(A)abc | (B)28c |
(C)abc28 | (D)因类型不一致而出错 |
【解析】由于“a+”的使用,在写操作时,文件指针直接指向文件尾部。
【答案】(C)