1、国家二级 C 语言(指针、编译预处理和动态存储分配)机试模拟试卷 2 及答案解析(总分:56.00,做题时间:90 分钟)一、选择题(总题数:28,分数:56.00)1.有以下程序:#includestdiohvoidf(int*p,int*q);main()int m=1,n=2,*r=&m;f(r,&n);printf(“d,d“,m,n);voidf(int*p,int*q)p=p+1:*q=*q+1:程序的运行结果是( )。(分数:2.00)A.2,3B.1,3C.1,4D.1,22.设已有定义 float x;,则下列对指针变量 p 进行定义且赋初值的语句中正确的是( )。(分数:2
2、.00)A.int*p=(float)x;B.float*p=&x;C.float p=&x;D.float*p=1024;3.若有定义语句 double a,*p=&a;,下列叙述中错误的是( )。(分数:2.00)A.定义语句中的*号是一个间址运算符B.定义语句中的*号是一个说明符C.定义语句中的 p 只能存放 double 类型变量的地址D.定义语句中,*p=&a 把变量 a 的地址作为初值赋给指针变量 P4.有以下程序:#includestdiohmain()int a=1,b=3,C=5;int*p1=&a,*p2=&b,*p=&c;*p=*p1*(*p2);printf(“dn“,
3、c);程序的运行结果是( )。(分数:2.00)A.1B.2C.3D.45.有以下程序:#includestdiohmain()int n,*p=NULL;*p=&n:printf(“Input n:“);seanf(“d“,&p);printf(“output n:“);printf(“dn“,p);该程序试图通过指针 p 为变量 n 读入数据并输出,但程序有多处错误,下列语句中正确的是( )。(分数:2.00)A.int n,*p=NULL;B.*p=&n;C.scanf(“d“,&p)D.printf(“dn“,p);6.若有定义语句 double x,y,*px,*py;,执行了 px
4、=&x;py=&y;之后,正确的输入语句是( )。(分数:2.00)A.seanf(“Ifle“,px,py);B.seanf(“ff“&x,&y);C.sccanf(“ff“,x,y);D.scanf(“IfIf“,x,y);7.下列程序段中完全正确的是( )。(分数:2.00)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);8.若有定义语句 int a23,*p3;,则以下语句中正确的是( )。(分数:2.00)A.p=a;B.p0=a;C
5、.p0=&a12;D.p1=&a;9.设有以下函数:void fun(int n,char*s),则下列对函数指针的定义和赋值均正确的是( )。(分数:2.00)A.void(*pf)(int,char);pf=&fun;B.void*pf();pf=fun;C.void*pf();*pf=fun;D.void(*pf)(int,char*);pf=fun;10.下列函数的功能是( )。void fun(char*a,char,*b)while(*b=*a)!=0)a+;b+;(分数:2.00)A.将 a 所指字符串赋给 b 所指空间B.使指针 b 指向 a 所指字符串C.将 a 所指字符串和
6、 b 所指字符串进行比较D.检查 a 和 b 所指字符串中是否有011.有以下程序:#ineludestdioh#define N4void fun(int aN,int b)int i;for(i=0;iN;i+)bi=aii-aiN-1-i;main()int xNN=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,YN,i;fun(x,y);for(i=0;iN;i+)printf(“d,“,yi);printf(“n“);程序的运行结果是( )。(分数:2.00)A.-3,-1,1,3,B.-12,-3,0,0,C.0,1,2,3,D.-3,-3,-3,-
7、3,12.有以下程序:#includestdioh#includestringhmain()char str20=“One*Wodd“,“One*Dream!“,*p=str1;printf(“d,“,strlen(p);printf(“sn“,p);程序的运行结果是( )。(分数:2.00)A.10,One*Dream!B.9,One*Dream!C.9,One*WorldD.10,One*World13.若有定义 int w35;,则以下不能正确表示该数组元素的表达式是( )。(分数:2.00)A.*(&w00+1)B.*(*w+3)C.*(*(W+1)D.*(W+1)414.下列语句组中
8、正确的是( )。(分数:2.00)A.char*s;s=“Olympic“;B.char s7;s=“Olympic“;C.char*s;s=“Olympic“;D.char s7;s=“Olympic“;15.有以下程序(注:字符 a 的 ASCII 码值为 97):#includestdiohmain()char*s=“abc“;doprintf(“d“,*s10);+s;while(*s);程序的运行结果是( )。(分数:2.00)A.789B.abeC.7890D.97989916.设有定义“char*c;”,以下选项中能够使 c 正确指向一个字符串的是( )。(分数:2.00)A.c
9、har str=“string“;c=str;B.scanf(“s“,c);C.c=getchar();D.*c=“string“;17.有以下函数:int fun(char*x,char*y)int n=0;while(*x=*y)&*x!=0)x+;y+;n+:return n:函数的功能是( )。(分数:2.00)A.将 y 所指字符串赋给 x 所指存储空间B.查找 x 和 y 所指字符串中是否有0C.统计 x 和 y 所指字符串中最前面连续相同的字符个数D.统计 x 和 y 所指字符串中相同的字符个数18.下列语句组中正确的是( )。(分数:2.00)A.char*s;s=“BOOK!
10、“;B.char*s;s=“BOOK!“;C.char*s10;s=“BOOK!“;D.char s;s=“BOOK!“;19.设有定义语句“int(*f)(int);”则下列叙述中正确的是( )。(分数:2.00)A.f 是基类型为 int 的指针变量B.f 是指向函数的指针变量,该函数具有一个 int 类型的形参C.f 是指向 int 类型一维数组的指针变量D.f 是函数名,该函数的返回值是基类型为 int 类型的地址20.有以下程序:#includestdiohint add(int a,int b)return(a+b);main()int k,(*f)(),a=5,b=10;f=ad
11、d;则以下函数调用语句错误的是( )。(分数:2.00)A.k=f(a,b);B.k=add(a,b);C.k=(*f)(a,b);D.k=*f(a,b);21.下列语句中存在语法错误的是( )。(分数:2.00)A.char ss620;ss1=“right?“;B.char ss20=“right?“;C.char*ss6;ss1=“right?“;D.char*ss=“right?“;22.下列叙述中正确的是( )。(分数:2.00)A.在 C 语言中,预处理命令行都以“#”开头B.预处理命令行必须位于 C 源程序的起始位置C.#includestdioh必须放在 C 程序的开头D.C
12、语言的预处理不能实现宏定义和条件编译的功能23.下列关于宏的叙述中正确的是( )。(分数:2.00)A.宏替换没有数据类型限制B.宏定义必须位于源程序中所有语句之前C.宏名必须用大写字母表示D.宏调用比函数调用耗费时间24.有以下程序:#includestdioh#define PT35:#define S(x)PT*x*x;main()int a=1,b=2;printf(“41fn“,S(a+b);程序的运行结果是( )。(分数:2.00)A.75B.315C.程序有错无输出结果D.14025.若程序中有宏定义行:#define N100,则下列叙述中正确的是( )。(分数:2.00)A.
13、宏定义行中定义了标识符 N 的值为整数 100B.在编译程序对 C 源程序进行预处理时用 100 替换标识符 NC.上述宏定义行实现将 100 赋给标识符 ND.在运行时用 100 替换标识符 N26.有以下程序:#includestdioh#define S(x)4*(x)*x+1main()int k=5,j=2;printf(“dn“,S(k+j);程序的运行结果是( )。(分数:2.00)A.33B.197C.143D.2827.有以下程序:#includestdioh#define SUB(a)(a)-(a)main()Int a=2,b=3,c=5,d;d=SUB(a+b)*c;p
14、rintf(“dn“,d);程序的运行结果是( )。(分数:2.00)A.0B.-12C.-20D.1028.下列叙述中错误的是( )。(分数:2.00)A.C 程序对预处理命令行的处理是在程序执行过程中进行的B.预处理命令行的最后不能以分号表示结束C.#define MAX 是合法的宏定义命令行D.在程序中,凡是以“#”开始的语句行都是预处理命令行国家二级 C 语言(指针、编译预处理和动态存储分配)机试模拟试卷 2 答案解析(总分:56.00,做题时间:90 分钟)一、选择题(总题数:28,分数:56.00)1.有以下程序:#includestdiohvoidf(int*p,int*q);m
15、ain()int m=1,n=2,*r=&m;f(r,&n);printf(“d,d“,m,n);voidf(int*p,int*q)p=p+1:*q=*q+1:程序的运行结果是( )。(分数:2.00)A.2,3B.1,3 C.1,4D.1,2解析:解析:在 f(int*p,int*q)函数中,执行 p=p+1 是将 p 所对应的地址加 1,而*q=*q+1 是将 q 所指向 n 的地址所对应的值加 1,所以 m 的值所对应的值没有变,而 n 的值则为 3 了,因此 B 选项正确。2.设已有定义 float x;,则下列对指针变量 p 进行定义且赋初值的语句中正确的是( )。(分数:2.00
16、)A.int*p=(float)x;B.float*p=&x; C.float p=&x;D.float*p=1024;解析:解析:指针是用来存放地址的变量,用(类型名*指针变量名)的形式定义。赋值时应将某个变量地址即&x 赋给指针变量,所以选择 B。3.若有定义语句 double a,*p=&a;,下列叙述中错误的是( )。(分数:2.00)A.定义语句中的*号是一个间址运算符 B.定义语句中的*号是一个说明符C.定义语句中的 p 只能存放 double 类型变量的地址D.定义语句中,*p=&a 把变量 a 的地址作为初值赋给指针变量 P解析:解析:在变量定义 double a,*p=&a;
17、中,水号是一个指针运算符,而非间址运算符,所以 A 错误。4.有以下程序:#includestdiohmain()int a=1,b=3,C=5;int*p1=&a,*p2=&b,*p=&c;*p=*p1*(*p2);printf(“dn“,c);程序的运行结果是( )。(分数:2.00)A.1B.2C.3 D.4解析:解析:该程序中 int*p1=&a,*p2=&b,*p=&c;指定义 3 个指针变量,并赋值,即使 p1 指向 a;p2指向 b;p 指向 c。*p=*p1*(*p2);语句是给 p 所指的存储单元 c 赋值,就是 p1 所指的存储单元的值,即a 的值,与 p2 所指的存储单元
18、 b 的值相乘,也就是 c=a*b,等价于 c=1*3=3,因此 C 选项正确。5.有以下程序:#includestdiohmain()int n,*p=NULL;*p=&n:printf(“Input n:“);seanf(“d“,&p);printf(“output n:“);printf(“dn“,p);该程序试图通过指针 p 为变量 n 读入数据并输出,但程序有多处错误,下列语句中正确的是( )。(分数:2.00)A.int n,*p=NULL; B.*p=&n;C.scanf(“d“,&p)D.printf(“dn“,p);解析:解析:B 选项的正确写法应为 p=&n;C 选项的正确
19、写法应为 scanf(“d“,p);选项 D 的正确写法应为 printf(“dn“,*p)。6.若有定义语句 double x,y,*px,*py;,执行了 px=&x;py=&y;之后,正确的输入语句是( )。(分数:2.00)A.seanf(“Ifle“,px,py); B.seanf(“ff“&x,&y);C.sccanf(“ff“,x,y);D.scanf(“IfIf“,x,y);解析:解析:因为 x 和 y 都是 double 型数据,所以输入时的格式字符应为lf,所以 B、C 选项错误。D选项中的 scanf(“lflf|,x,y);应为 scanf(“lflf“,&x,&y);
20、。7.下列程序段中完全正确的是( )。(分数:2.00)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);解析:解析:A 选项中错在没有对指针进行初始化,无效指针,并且在 scanf(“d“,&p)中无须再进行取地址操作;B 选项中没有对指针进行初始化,无效指针;D 选项中语句*p=&k;的左端*p 是指针所指内存空间的值,&k 是地址,应为 p=&k。C 选项正确。8.若有定义语句 int a23,*p3;,则以下语句中正确的是( )。(分数
21、:2.00)A.p=a;B.p0=a;C.p0=&a12; D.p1=&a;解析:解析:A 选项错误,因为 p 是指向一个指针数组,作为数组名,不能指向别的地方。B 选项错误,因为 p0是一个 int 指针,也就是 int*;而 a 是一个指向指针的指针 int*。C 选项正确,因为 p0是一个 int*,a12是 int,&a12是 int*,类型吻合。D 选项错误,因为 a 作为数组名,不能取地址,即使能取,p1是 int*,&a 是 int*,类型不对。9.设有以下函数:void fun(int n,char*s),则下列对函数指针的定义和赋值均正确的是( )。(分数:2.00)A.vo
22、id(*pf)(int,char);pf=&fun;B.void*pf();pf=fun;C.void*pf();*pf=fun;D.void(*pf)(int,char*);pf=fun; 解析:解析:函数的参数可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。函数名代表函数的入口地址,指向函数的指针应该定义为 void(*pf)()。如果定义为 void*pf(),则表示函数 pf 的返回值是一个基类型为 void 的指针,因此 D 选项正确。10.下列函数的功能是( )。void fun(char*a,char,*b)while(*b=*a)!=0)a+;b+;(分数:2.0
23、0)A.将 a 所指字符串赋给 b 所指空间 B.使指针 b 指向 a 所指字符串C.将 a 所指字符串和 b 所指字符串进行比较D.检查 a 和 b 所指字符串中是否有0解析:解析:while 循环条件为:(*b=*a)!=0,执行时先把指针 a 所指向的字符赋给指针 b 所在的内存单元,如果该字符不是结束标识“0”,执行循环体“a+;b+;”,指针 a、b 分别指向下一个字符单元。再判断循环条件,如果成立,继续把指针 a 所指向的字符赋给指针 b 所在的内存单元,直到遇到结束标识为止,因此 A 选项正确。11.有以下程序:#ineludestdioh#define N4void fun(i
24、nt aN,int b)int i;for(i=0;iN;i+)bi=aii-aiN-1-i;main()int xNN=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,YN,i;fun(x,y);for(i=0;iN;i+)printf(“d,“,yi);printf(“n“);程序的运行结果是( )。(分数:2.00)A.-3,-1,1,3, B.-12,-3,0,0,C.0,1,2,3,D.-3,-3,-3,-3,解析:解析:本题由 fun 函数可知,b0=a00-a03=1-4=-3,b1=a11-12=6-7=-1,b2=a22-21=11-10=1,b
25、3=a33-31=16-13=3,所以主函数中打印 y 数组元素的值为 A 选项。12.有以下程序:#includestdioh#includestringhmain()char str20=“One*Wodd“,“One*Dream!“,*p=str1;printf(“d,“,strlen(p);printf(“sn“,p);程序的运行结果是( )。(分数:2.00)A.10,One*Dream! B.9,One*Dream!C.9,One*WorldD.10,One*World解析:解析:p 是指向二维字符数组第二行 One*Dream!的数组指针,所以长度是 10,打印输出的也是该字符串
26、。13.若有定义 int w35;,则以下不能正确表示该数组元素的表达式是( )。(分数:2.00)A.*(&w00+1)B.*(*w+3)C.*(*(W+1)D.*(W+1)4 解析:解析:A 选项中*(&w00+1)表示 w01;B 选项中*(*w+3)表示 w03;C 选项中*(*(w+1)表示 w10;而 D 选项中*(w+1)4的正确写法是(*w+1)4,表示 w14,因此选择 D 选项。14.下列语句组中正确的是( )。(分数:2.00)A.char*s;s=“Olympic“; B.char s7;s=“Olympic“;C.char*s;s=“Olympic“;D.char s
27、7;s=“Olympic“;解析:解析:字符型指针变量可以用 A 选项的赋值方法:char*s;s=“Olympic“。C 选项的写法:char*s,s=“Olympic“;是错误的。字符数组可以在定义的时候初始化:char s=“Olympic“;或者char s=“Olympic“,但是不可以在定义字符数组后对数组名赋值(数组名是常量,代表数组首地址),所以 B 选项和 D 选项都是错误的。对于本例,B、D 选项中字符数组 s 的大小至少为 8,才能存放下字符串(字符串的末尾都有结束标志0),同时此时 s 为字符数组的地址,是常量,不能为其赋值。15.有以下程序(注:字符 a 的 ASCI
28、I 码值为 97):#includestdiohmain()char*s=“abc“;doprintf(“d“,*s10);+s;while(*s);程序的运行结果是( )。(分数:2.00)A.789 B.abeC.7890D.979899解析:解析:因为小写字符 a、b、c 的 ASCII 码值分别为 97、98、99,而在 do while 循环语句中,每次对字符的 ASCII 码值取余数并输出,所以分别输出 7、8、9。16.设有定义“char*c;”,以下选项中能够使 c 正确指向一个字符串的是( )。(分数:2.00)A.char str=“string“;c=str; B.sca
29、nf(“s“,c);C.c=getchar();D.*c=“string“;解析:解析:选项 A 为正确用法,先将字符串存于字符数组中,然后将数组名赋给字符指针(数组名代表数组首地址,定义数组时为其分配确定的地址)。C 选项错误,getchar()函数输入一个字符给字符型变量,而不是字符指针。B 选项和 D 选项有类似的错误,两个选项并无语法错误,但运行时可能会出现问题。因为在 B 选项和 D 选项中,字符指针没有被赋值,是个不确定的值,指向一个不确定的内存区域,这个区域可能存放有用的指令或数据。在这个不确定的区域重新存放字符串,可能会发生无法预知的错误。17.有以下函数:int fun(ch
30、ar*x,char*y)int n=0;while(*x=*y)&*x!=0)x+;y+;n+:return n:函数的功能是( )。(分数:2.00)A.将 y 所指字符串赋给 x 所指存储空间B.查找 x 和 y 所指字符串中是否有0C.统计 x 和 y 所指字符串中最前面连续相同的字符个数 D.统计 x 和 y 所指字符串中相同的字符个数解析:解析:本题中由循环条件可知,遇到0或 x 与 y 所指的字符的值不等中的一个条件时就结束,所以功能是统计 x 和 y 所指字符串中最前面连续相同的字符个数。18.下列语句组中正确的是( )。(分数:2.00)A.char*s;s=“BOOK!“;B
31、.char*s;s=“BOOK!“; C.char*s10;s=“BOOK!“;D.char s;s=“BOOK!“;解析:解析:A 选项去掉大括号就正确了;C 选项和 D 选项应在定义时赋初值。B 选项正确。19.设有定义语句“int(*f)(int);”则下列叙述中正确的是( )。(分数:2.00)A.f 是基类型为 int 的指针变量B.f 是指向函数的指针变量,该函数具有一个 int 类型的形参 C.f 是指向 int 类型一维数组的指针变量D.f 是函数名,该函数的返回值是基类型为 int 类型的地址解析:解析:int(*f)(int);为指向函数的指针变量的定义方法,其中 f 为指
32、向函数的指针变量,第一个int 为函数返回值类型,第二个 int 为函数的形参类型,因此 B 选项正确。20.有以下程序:#includestdiohint add(int a,int b)return(a+b);main()int k,(*f)(),a=5,b=10;f=add;则以下函数调用语句错误的是( )。(分数:2.00)A.k=f(a,b);B.k=add(a,b);C.k=(*f)(a,b);D.k=*f(a,b); 解析:解析:D 选项中,*f(a,b)表示调用后返回一个指向整型数据的地址指针,即该函数的返回值为指针类型,所以不能将其赋值给整形变量 k。21.下列语句中存在语法
33、错误的是( )。(分数:2.00)A.char ss620;ss1=“right?“; B.char ss20=“right?“;C.char*ss6;ss1=“right?“;D.char*ss=“right?“;解析:解析:数组定义后,不可以对数组整体赋值,s 是二维数组,因 ss1是一维字符数组,即字符串,字符串赋值可以使用“strcpy(ss1,“right“);”这样的形式,而 A 选项中对二维数组中的第“1”维(相当于一个一维数组)赋值是不可以的。B 选项和 D 选项是定义时对数组初始化,这是可以的。在 C 选项中,将字符串在内存中的首地址赋给指针数组的一个元素,这是可以的。22.
34、下列叙述中正确的是( )。(分数:2.00)A.在 C 语言中,预处理命令行都以“#”开头 B.预处理命令行必须位于 C 源程序的起始位置C.#includestdioh必须放在 C 程序的开头D.C 语言的预处理不能实现宏定义和条件编译的功能解析:解析:预处理命令是以“#”号开头的命令,它们不是 C 语言的可执行命令,这些命令应该在函数之外书写,一般在源文件的最前面书写,但不是必须在起始位置书写,所以 B、C 选项错误。C 语言的预处理能够实现宏定义和条件编译等功能,所以 D 选项错误。23.下列关于宏的叙述中正确的是( )。(分数:2.00)A.宏替换没有数据类型限制 B.宏定义必须位于源
35、程序中所有语句之前C.宏名必须用大写字母表示D.宏调用比函数调用耗费时间解析:解析:宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头,所以 B 选项中“宏定义必须位于源程序中所有语句之前”是错误的。宏名一般用大写,但不是必须用大写,所以 C 选项错误。宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值),所以 D 选项错误。24.有以下程序:#includestdioh#define PT35:#define S(x)PT*x*x;main()int a=1,b=2;printf(“41fn“,S(a+b);程序的运行结果是( )。(分数
36、:2.00)A.75B.315C.程序有错无输出结果 D.140解析:解析:宏定义不是 C 语句,末尾不需要有分号,语句 printf(“41fn“,s(a+b);展开后为printf(“41fn“,35;*a+b*a+b;);,所以程序会出现语法错误。25.若程序中有宏定义行:#define N100,则下列叙述中正确的是( )。(分数:2.00)A.宏定义行中定义了标识符 N 的值为整数 100B.在编译程序对 C 源程序进行预处理时用 100 替换标识符 N C.上述宏定义行实现将 100 赋给标识符 ND.在运行时用 100 替换标识符 N解析:解析:本题考查预编译相关知识,宏定义在编
37、译程序时做了一个简单的替换,所以 B 选项正确。26.有以下程序:#includestdioh#define S(x)4*(x)*x+1main()int k=5,j=2;printf(“dn“,S(k+j);程序的运行结果是( )。(分数:2.00)A.33B.197C.143 D.28解析:解析:本题考查带参数的宏定义,s 为带参数的宏定义,运行 s(k+j)为 4*(k+j)*k+j+1=143,C 选项正确。27.有以下程序:#includestdioh#define SUB(a)(a)-(a)main()Int a=2,b=3,c=5,d;d=SUB(a+b)*c;printf(“dn“,d);程序的运行结果是( )。(分数:2.00)A.0B.-12C.-20 D.10解析:解析:本题考查宏定义。宏定义只是做简单的替换,本题中 SUB(a+b)*c=(a+b)-(a+b)*c=-20,所以 C 选项正确。28.下列叙述中错误的是( )。(分数:2.00)A.C 程序对预处理命令行的处理是在程序执行过程中进行的 B.预处理命令行的最后不能以分号表示结束C.#define MAX 是合法的宏定义命令行D.在程序中,凡是以“#”开始的语句行都是预处理命令行解析:解析:本题考查预处理命令行。预处理是在程序编译之前进行的,所以 A 选项错误。