1、国家二级 C 语言机试(翻译预处理和指针)模拟试卷 11 及答案解析(总分:50.00,做题时间:90 分钟)一、选择题(总题数:25,分数:50.00)1.关于 C 语言预处理命令的叙述中正确的是( )。(分数:2.00)A.在 C 语言中,预处理命令行都以“#”开头B.预处理命令行必须位于 C 源程序的起始位置C.#include 必须放在 C 程序的起始位置D.C 语言的预处理不能实现宏定义和条件编译的功能2.关于宏的叙述中正确的是( )。(分数:2.00)A.宏名称必须用大写字母表示B.宏定义必须位于源程序中所有语句之前C.宏调用比函数调用耗费时间D.宏替换没有数据类型限制3.设#de
2、fine IsDIV(k,n)(kn=1)?1:0),则宏调用:IsDIV(m,5)&IsDIV(m,7)为真时所要表达的是( )。(分数:2.00)A.判断 m 是否能被 5 和 7 同时整除B.判断 m 被 5 或者 7 整除是否余 1C.判断 m 被 5 和 7 整除是否都余D.判断 m 是否能被 5 或者 7 整除4.以下程序的输出结果是( )。 #include #define f(x)x*x*x main()int a=3,s,t; s=f(a+1); t=f(a+1); printf(d,dn,s,t);(分数:2.00)A.64,10B.10,64C.10,10D.64,645
3、.关于预处理命令的叙述中错误的是( )。(分数:2.00)A.预处理命令行的最后不能以分号表示结束B.C 程序对预处理命令行的处理是在程序执行的过程中进行的C.#define MAX 是合法的宏定义命令行D.在程序中凡是以“#”开始的语句行都是预处理命令行6.以下程序的输出结果是( )。#deftne S(x)x*x#define T(x)S(x)*S(x)main()int k=5,j=2;printf(d,dn,S(k+j),T(k+j);(分数:2.00)A.17,37B.49,289C.17,289D.49,24017.关于#include 的叙述中正确的是( )。(分数:2.00)A
4、.在包含文件中,不得再包含其他文件B.#include 命令行不能出现在程序文件的中间C.在一个程序中,允许使用任意数量的#include 命令行D.虽然包含文件被修改了。包含该文件的源程序也可以不重新进行编译和连接8.设 void fun(int n,char *s),则下面对函数指针的定义和赋值均正确的是( )。(分数:2.00)A.void *pf();*pf=fun;B.void (*pf)(int,char*);pf=fun;C.void *pf();pf=fun;D.void (*pf)(int,char);pf=&fun;9.关于变量和地址的叙述中正确的是( )。(分数:2.00
5、)A.语句 p=NULL;执行后,指针 P 指向地址为 0 的存储单元B.语句p=NULL;与p=0;是等价的语句C.“int*p1;int*p2;int*p3;”都是合法的定义指针变量的语句D.指针变量只能通过求地址运算符(&)来获得地址值10.关于 int* func(int a10,int n);的叙述中正确的是( )。(分数:2.00)A.说明中的 a10写成 a或*a 效果完全一样B.形参 a 对应的实参只能是数组名C.func 的函数体中不能对 a 进行移动指针(如 a+)的操作D.只有指向 10 个整数内存单元的指针,才能作为实参传给 a11.关于地址的叙述中错误的是( )。(分
6、数:2.00)A.改变函数形参的值,不会改变对应实参的值B.函数可以返回地址值C.当在程序的开头包含头文件 stdioh 时,可以给指针变量赋:NULLD.可以给指针变量赋一个整数作为地址值12.23以下程序的输出结果是( )。main()int m=1,n=2,*p=&m,*q=&n,*r;r=p;p=q;q=r;printf(d,d,d,dn,m,n,*P,*q);(分数:2.00)A.2,1,2,1B.1,2,2,1C.1,2,1,2D.2,1,1,213.设 float a10,*s=a;以下能够代表数组元素 a3的是( )。(分数:2.00)A.(*s)3B.*s3C.*s+3D.*
7、(s+3)14.若 int a23,*p3;则以下语句中正确的是( )。(分数:2.00)A.p0=&a12;B.p0=a;C.*p+=1;D.p=a;15.若 float a,*p=&a;以下叙述中错误的是( )。(分数:2.00)A.定义语句中的*是一个说明符B.定义语句中的 P 只能存放 float 类型变量的地址C.定义语句中木 p=&a 把变量 a 的地址作为初值赋给指针变量 pD.定义语句中的*是一个间址运算符16.以下程序的输出结果是( )。int fun1(double A)return a*=a;int fun2(double x,double y)double a=0,b=
8、0;a=fun1(x);b=fun1(y);return(int)(a+b);main()double w;w=fun2(11,20);(分数:2.00)A.500B.40C.421D.5017.以下程序的输出结果是( )。void fun(int n,int *s)int f;if(n=1)*s=n+1;elsefun(n 一1,&f);*s=f;main()int x=0;fun(4,&x);printf(dn,x);(分数:2.00)A.4B.3C.1D.218.以下程序的输出结果是( )。 #include main() #define N 4 int xN=1,2,3),4),5,6
9、,7,8),9,10, void fun(int aN,int b) yN,i; int i; fun(x,y); for(i=0;iN;i+)bi=aii; for(i=0;iN;i+)printf(d,yi); printf(n);(分数:2.00)A.3,4,8,10,B.1,4,5,9,C.1,0,7,0,D.1,2,3,4,19.以下程序的输出结果是( )。 #include main() void fun(char *c,int d) char b=a,a=A; *c=*c+1;d=d+1; fun(&b,a);printf(c,cn,b,a); printf(c,c,*c,d);
10、(分数:2.00)A.b,B,b,AB.a,B,a,BC.a,B,B,aD.b,B,B,A20.以下程序的输出结果是( )。 #include int funa(int a,int b)return a+b; int funb(int a,int b)return a 一 b; int sss(int(*t)(),jnt x,int y)retern(*t)(x,y); main()int x; x=sss(funa,9,3); x+=sss(funb,8,3); printf(dn,x);(分数:2.00)A.17B.22C.24D.2321.以下程序的输出结果是( )。void fun(i
11、nt *p,int* q)int t;t=*P;*P=*q;*q=t;*q=*p;main()int a=0,b=9;fun(&a,&b);printf(dn,a,b);(分数:2.00)A.9 0B.9 9C.0 0D.0 922.以下程序的输出结果是( )。void swap(char*x,char*y) main()char t; char*s1=abc,*s2=123*;t=*x;*x=*y;*y=t; swap(s1,s2);printf(s,sn,s1,s2); (分数:2.00)A.321,cbaB.123,abcC.abc,123D.1bc,a2323.以下函数的功能是( )。
12、int fun(char*s)char*t=s;while(*t+);return(t 一 s);(分数:2.00)A.计算 s 所指字符串的长度B.比较两个字符串的大小C.计算 s 所指字符串占用内存字节的个数D.将 s 所指字符串复制到字符串 t 中24.以下程序的输出结果是( )。 #include void fun(char*P) +p;printf(sh,*P); main() char*a=Morning,Afternoon,Evening,Night); fun(a);(分数:2.00)A.MorningB.fternoonC.orningD.Afternoon25.以下程序的输
13、出结果是( )。 #include main() void fun(char*a,char*b) char*s=*a*b*,t80; while(*a=*)a+; fun(s,t);puts(t); while(*b=*a)b+;a+; (分数:2.00)A.abB.*a*bC.a*b*D.a*b国家二级 C 语言机试(翻译预处理和指针)模拟试卷 11 答案解析(总分:50.00,做题时间:90 分钟)一、选择题(总题数:25,分数:50.00)1.关于 C 语言预处理命令的叙述中正确的是( )。(分数:2.00)A.在 C 语言中,预处理命令行都以“#”开头 B.预处理命令行必须位于 C 源
14、程序的起始位置C.#include 必须放在 C 程序的起始位置D.C 语言的预处理不能实现宏定义和条件编译的功能解析:解析:C 语言规定,凡是以“#”开头的行,都称为“编译预处理”命令行。预处理命令可以放在程序中的任何位置。其有效范围是从定义开始到文件结束。预处理命令有宏定义、文件包含和条件编译三类。#include 命令行表示程序中要引用 C 标准函数库中的标准输入输出函数。2.关于宏的叙述中正确的是( )。(分数:2.00)A.宏名称必须用大写字母表示B.宏定义必须位于源程序中所有语句之前C.宏调用比函数调用耗费时间D.宏替换没有数据类型限制 解析:解析:本题考查宏替换的规则。使用宏时应
15、注意几点:宏定义仅仅是符号替换,不是赋值语句,因此不做语法检查;为了区别程序中其他的标识符,宏名的定义通常用大写字母,但不是必须用大写;双引号中出现的宏名不替换;使用宏定义可以嵌套,即后定义的宏中可以使用先定义的宏。3.设#define IsDIV(k,n)(kn=1)?1:0),则宏调用:IsDIV(m,5)&IsDIV(m,7)为真时所要表达的是( )。(分数:2.00)A.判断 m 是否能被 5 和 7 同时整除B.判断 m 被 5 或者 7 整除是否余 1C.判断 m 被 5 和 7 整除是否都余 D.判断 m 是否能被 5 或者 7 整除解析:解析:本题考查宏定义和三目运算符。三目运
16、算符:test?语句 1:语句 2;其中,test 可以是任何表达式。语句 1,当 test 是非零时执行该语句,可以是复合语句;语句 2,当 test 是零时执行该语句,可以是复合语句。IsDIV(k,n)要表达的是当 k 除 n 的余数是 1 时表达式的值为 1,否则为 0,所以题中要表达的是 m 被 5 和 7 整除是否都余 1。4.以下程序的输出结果是( )。 #include #define f(x)x*x*x main()int a=3,s,t; s=f(a+1); t=f(a+1); printf(d,dn,s,t);(分数:2.00)A.64,10B.10,64 C.10,10
17、D.64,64解析:解析:根据题中宏 f(x)的定义,运算过程应为:s=f(a+1)=a+1*a+1*a+1=a+a+a+1=10,因此最后 s的结果为 10,而 f(a+1)=(a+1)*(a+1)*(a+1)=4*4*4=64 的结果为 64。5.关于预处理命令的叙述中错误的是( )。(分数:2.00)A.预处理命令行的最后不能以分号表示结束B.C 程序对预处理命令行的处理是在程序执行的过程中进行的 C.#define MAX 是合法的宏定义命令行D.在程序中凡是以“#”开始的语句行都是预处理命令行解析:解析:C 语言中预处理命令行是以“#”开始的语句,预处理命令行的最后不能以分号表示结束
18、。其中宏定义的字符替换的定义格式为:#define 标识符字符串,预处理命令行是在系统对源程序进行编译之前进行处理的,不是在程序执行的过程中。6.以下程序的输出结果是( )。#deftne S(x)x*x#define T(x)S(x)*S(x)main()int k=5,j=2;printf(d,dn,S(k+j),T(k+j);(分数:2.00)A.17,37 B.49,289C.17,289D.49,2401解析:解析:本题考查了宏替换,C 语言中的宏替换不会进行语法错误检查也不会进行运算。“S(k+i)”宏展开以后为“k+j*k+j”,值为 17,“T(k+j)”宏展开以后为“k+j*
19、k+j*k+j*k+j”值为 37。7.关于#include 的叙述中正确的是( )。(分数:2.00)A.在包含文件中,不得再包含其他文件B.#include 命令行不能出现在程序文件的中间C.在一个程序中,允许使用任意数量的#include 命令行 D.虽然包含文件被修改了。包含该文件的源程序也可以不重新进行编译和连接解析:解析:C 语言的预编译处理符号 include 具有以下规则: 包含文件的 include 命令行通常应书写在所用源程序文件的开头,故有时也把包含文件称作“头文件”。头文件名可以由用户指定,其后缀不一定用“h”; 包含文件中,一般包含有一些公用的#define 命令行、
20、外部说明或对(库)函数的原型说明; 当包含文件修改后,对包含该文件的源程序必须重新进行编译链接; 在一个程序中,允许有任意多个#include 命令行; 在包含文件中还可以包含其他文件。8.设 void fun(int n,char *s),则下面对函数指针的定义和赋值均正确的是( )。(分数:2.00)A.void *pf();*pf=fun;B.void (*pf)(int,char*);pf=fun; C.void *pf();pf=fun;D.void (*pf)(int,char);pf=&fun;解析:解析:void(*pf)()定义了一个没有返回值的函数指针 pf,在给函数指针变
21、量赋值时,只需给出函数名而不必给出参数。所以给 pf 赋值时,把函数名 fun 赋给 pf 即可。9.关于变量和地址的叙述中正确的是( )。(分数:2.00)A.语句 p=NULL;执行后,指针 P 指向地址为 0 的存储单元B.语句p=NULL;与p=0;是等价的语句C.“int*p1;int*p2;int*p3;”都是合法的定义指针变量的语句 D.指针变量只能通过求地址运算符(&)来获得地址值解析:解析:C 语言规定指针变量赋地址值的方式有 3 种方式:通过求地址运算符(&)获得地址值;通过指针变量获得地址值;通过标准函数获得地址值。另外 NULL 是在 stdioh 头文件中定义的预定义
22、符。NULL 的代码值为 0。可以给指针变量赋 NULL 值。例如 p=NULL;赋值语句,称 p 为空指针。这条语句等价于 p=0;或 p=0;这时,指针 p 并不是指向地址为 0 的存储单元,而是具有一个确定的值“空”。10.关于 int* func(int a10,int n);的叙述中正确的是( )。(分数:2.00)A.说明中的 a10写成 a或*a 效果完全一样 B.形参 a 对应的实参只能是数组名C.func 的函数体中不能对 a 进行移动指针(如 a+)的操作D.只有指向 10 个整数内存单元的指针,才能作为实参传给 a解析:解析:函数 func 为返回值为指针的函数,有两个形
23、参,形参数组 a 为指针变量,保存实参数组的首地址,其元素个数由实参数组决定,因此说明中的 a10可以写成 a或*a。11.关于地址的叙述中错误的是( )。(分数:2.00)A.改变函数形参的值,不会改变对应实参的值B.函数可以返回地址值C.当在程序的开头包含头文件 stdioh 时,可以给指针变量赋:NULLD.可以给指针变量赋一个整数作为地址值 解析:解析:C 语言中指针变量的值只能是存储单元地址,而不能是一个整数,选项 D 的描述错误。函数可以返回内存空间的地址,同时函数形参和实参分别占用不同的内存单元,改变形参的值不会改变对应实参的值,在头文件 stdioh 中,NULL 被定义为 v
24、oid 型的指针。12.23以下程序的输出结果是( )。main()int m=1,n=2,*p=&m,*q=&n,*r;r=p;p=q;q=r;printf(d,d,d,dn,m,n,*P,*q);(分数:2.00)A.2,1,2,1B.1,2,2,1 C.1,2,1,2D.2,1,1,2解析:解析:题目中在主函数定义了 3 个整数指针变量 p,q,r,并且使 p 指向 m,q 指向 n,再执行“r=p;p=q;q=r;”这三条语句,使 q 指向 m,p 指向 n,再输出变量“m,n,*p,*q”时,它们值分别为 1,2,2,1。13.设 float a10,*s=a;以下能够代表数组元素
25、a3的是( )。(分数:2.00)A.(*s)3B.*s3C.*s+3D.*(s+3) 解析:解析:C 语言中,指针可以指向一个数组,语句*s=a,使用指针变量 s 指向一维数组 a 的首地址,所以*(s+3)表示的是引用数组 a3。14.若 int a23,*p3;则以下语句中正确的是( )。(分数:2.00)A.p0=&a12; B.p0=a;C.*p+=1;D.p=a;解析:解析:题目中定义语句“int a23,*p3;”定义了整型二维数组 a23和指针数组 p3。在 C 语言中,二维数组名也是一个存放地址常量的指针,其值为二维数组中第一行的地址。所以选项 A 中,把整型数组元素 a12
26、的地址赋给 p0。15.若 float a,*p=&a;以下叙述中错误的是( )。(分数:2.00)A.定义语句中的*是一个说明符B.定义语句中的 P 只能存放 float 类型变量的地址C.定义语句中木 p=&a 把变量 a 的地址作为初值赋给指针变量 pD.定义语句中的*是一个间址运算符 解析:解析:在指针定义语句“float a,*p=&a”中,指针变量 p 前面的*只是一个说明符,说明变量 p是指针类型的变量。16.以下程序的输出结果是( )。int fun1(double A)return a*=a;int fun2(double x,double y)double a=0,b=0;
27、a=fun1(x);b=fun1(y);return(int)(a+b);main()double w;w=fun2(11,20);(分数:2.00)A.500 B.40C.421D.50解析:解析:题目中子函数 funl(double A)的功能是返回 a 的平方值的整数部分。子函数 fun2(double x,double y)的功能是返回 x 的平方值的整数部分与 y 的平方值的整数部分的和。又因为题中变量 w 的定义为 double 型,函数 fun2 的定义为 int 型,按照各类数值型数据间的混合运算,整型数据被转换为实型数据。所以双精度型变量 w 的值为 500。17.以下程序的
28、输出结果是( )。void fun(int n,int *s)int f;if(n=1)*s=n+1;elsefun(n 一1,&f);*s=f;main()int x=0;fun(4,&x);printf(dn,x);(分数:2.00)A.4B.3C.1D.2 解析:解析:题目中函数 fun 为递归调用函数,如果 n 的值为 1,那么后面形参指向的空间存放 n+1,否则继续计算 fun(n 一 1)的值。调用分析过程:fun(4,&x)fun(3,&x)fun(2,&x)fun(1,&x)在回归的过程中,对于 x 内的数据并没有改动。18.以下程序的输出结果是( )。 #include ma
29、in() #define N 4 int xN=1,2,3),4),5,6,7,8),9,10, void fun(int aN,int b) yN,i; int i; fun(x,y); for(i=0;iN;i+)bi=aii; for(i=0;iN;i+)printf(d,yi); printf(n);(分数:2.00)A.3,4,8,10,B.1,4,5,9,C.1,0,7,0, D.1,2,3,4,解析:解析:题目中函数 fun(int aN,int b)的功能是把矩阵 aNN主对角线上的元素赋给一维数组 b。在主函数中由 xN的初始化可知,其主对角线上的元素是 1,0,7,0。所以
30、当执行完函数fun(x,v)后,一维数组 y中的元素值为 1,0,7,0,选项为 C。19.以下程序的输出结果是( )。 #include main() void fun(char *c,int d) char b=a,a=A; *c=*c+1;d=d+1; fun(&b,a);printf(c,cn,b,a); printf(c,c,*c,d);(分数:2.00)A.b,B,b,A B.a,B,a,BC.a,B,B,aD.b,B,B,A解析:解析:本题中 fun 函数的参数传递方式有两类,形参 c 是传地址,形参 d 是传值,所以在主函数中,执行 fun 时,把变量 b 的地址传给了 c,把
31、 a 的值传递给了 d,经过运算,输出的值为 b,B。在主函数的输出语句中,输出变量 b 的值为 b,变量 a 的值为 A。20.以下程序的输出结果是( )。 #include int funa(int a,int b)return a+b; int funb(int a,int b)return a 一 b; int sss(int(*t)(),jnt x,int y)retern(*t)(x,y); main()int x; x=sss(funa,9,3); x+=sss(funb,8,3); printf(dn,x);(分数:2.00)A.17 B.22C.24D.23解析:解析:题目中
32、函数 funa 的功能计算两个数据的和,funb 的功能计算两个数据的差,函数 sss 中利用指向函数的指针作为函数的参数,可以在调用的时候,根据接收的函数地址来决定调用哪一个函数。主函数中调用 x=sss(funa,9,3),将 funa 函数的地址传递给 t,因此 sss 函数成为求两个数据的和 12,继续将 funb 函数地址传给 t,求两个数据差为 5,和 x 累加后结果为 17,选项 A 正确。21.以下程序的输出结果是( )。void fun(int *p,int* q)int t;t=*P;*P=*q;*q=t;*q=*p;main()int a=0,b=9;fun(&a,&b)
33、;printf(dn,a,b);(分数:2.00)A.9 0B.9 9 C.0 0D.0 9解析:解析:题目中函数 fun 的主要功能是交换 p 和 q 指向的地址空间的数据,然后更改 p 的指向的地址空间数据,使之和 q 指向的数据相同。主函数调用 fun 后,p 指向 a,q 指向 b,因此 ab 的数据全部为9,选项 B 正确。22.以下程序的输出结果是( )。void swap(char*x,char*y) main()char t; char*s1=abc,*s2=123*;t=*x;*x=*y;*y=t; swap(s1,s2);printf(s,sn,s1,s2); (分数:2.
34、00)A.321,cbaB.123,abcC.abc,123D.1bc,a23 解析:解析:题目中函数 void swap(char*x,char*y)的功能是交换两个字符*x 和*y 中的内容。在主函数中字符指针 s1 指向字符串abc,s2 指向字符串123。所以函数 swap(s1,s2)的执行结果就是字符a和1相互交换。23.以下函数的功能是( )。int fun(char*s)char*t=s;while(*t+);return(t 一 s);(分数:2.00)A.计算 s 所指字符串的长度 B.比较两个字符串的大小C.计算 s 所指字符串占用内存字节的个数D.将 s 所指字符串复制
35、到字符串 t 中解析:解析:题目中在函数 fun(char*s)中,首先用字符指针变量 t 指向 s,而循环语句 wliile(*t+);的功能是使指针变量 t 指向字符串变量 s 的末尾,这时退出循环,因而语句 return(ts);返回的就是字符串 s 所指字符串的长度。选项 A 正确。24.以下程序的输出结果是( )。 #include void fun(char*P) +p;printf(sh,*P); main() char*a=Morning,Afternoon,Evening,Night); fun(a);(分数:2.00)A.MorningB.fternoonC.orningD
36、.Afternoon 解析:解析:题目中指针的指针变量 a 和 p 都是指向字符串的指针。执行 fun(a)语句时,p 指向的是字符串数组 a 的第一个字符串“Morning”,p 自加 1 之后,*p 指向了字符串数组 a 的第 2 个字符串“Afternoon”。25.以下程序的输出结果是( )。 #include main() void fun(char*a,char*b) char*s=*a*b*,t80; while(*a=*)a+; fun(s,t);puts(t); while(*b=*a)b+;a+; (分数:2.00)A.abB.*a*bC.a*b* D.a*b解析:解析:题目中主函数 main()定义了指向字符串的指针和一个字符数组,接着调用 fun(s,t)函数,进行实参向形参传递,函数 fun 第一个 while 语句判断*a 中的值为木时继续扫描,当遇到不是*的字符时结束,接着第二个 while 循环语句,将*a 中从“a”开始的后续所有字符都赋予 b,也就是 t80中的内容为“a*b*”。