全国计算机二级C语言 # 选择题:编译预处理(1-44)
1. 有以下程序
#include <stdio.h>
main()
{
int i=1, j=3;
printf(“%d,” ,i++ );
{ int i=0;
i+=j*2;
printf(“%d,%d,” ,i,j );
}
printf(“%d,%d ” ,i,j );
}
程序运行后的输出结果是答案:B
A)1,7,3,2,3
B)1,6,3,2,3
C)1,6,3,1,3
D)1,6,3,6,3
题目解析:不同作用域内若定义有同名的局部变量,则在其中一个局部变量的作用域内,其他同名的局部变量会被”屏蔽”,规则一般是作用域小的变量”屏蔽”作用域大的变量。在用{}引起来的复合语句块中,i值为6,输出结果为6,3,而在语句块外,i为2,输出结果为2,3。
#include <stdio.h>
int fun(int a,int b)
{
static int m=0, i=2;
i +=m+1; m = i + a + b;
return m;
}
main()
{
int k=4, m=1, p;
p = fun( k,m ); printf(“%d,”, p);
p = fun( k,m ); printf(“%d ” ,p );
}
程序运行后的输出结果是答案:A
A)8,17
B)8,8
C)8,16
D)8,20
题目解析:静态变量定义时的初始化只运行一次,并且其值在程序运行过程中一直存在,所以第一次调用fun(k,m)时,p=fun(4,1)=m=8,静态变量i=2+0+1=3,m=3+4+1=8;第二次调用fun(k,m)时,p=fun(4,1)=m=17,静态变量i=3+8+1=12,m=12+4+1=17;输出结果为8,17。
3. 有以下程序
#include <stdio.h>
#define F(x) 2.84+x
#define PR(a) printf(“%d” ,(int)(a))
#define PRINT(a) PR(a);putchar(‘ ‘)
main()
{
PRINT( F(5)*2 );
}
程序运行后的输出结果是答案:A
A)12
B)15
C)11
D)13
题目解析:宏替换是使用宏名代替一个字符串,是一种机械、简单的置换,所以语句”PRINT(F(5)*2);”可用字符串”PR(F(5)*2);putchar(′′);”替换,而语句”PR(F(5)*2);”可以用字符串”printf(“%d”,(int)(F(5)*2))”,即为”printf(“%d” ,(int)(2.84+5*2)”,所以输出结果为12。
4. 有以下程序
#include <stdio.h>
main()
{ char c=’A’;
int x=36, b;
b= (x>>2) && ( c<‘a’ );
printf(“%d “, b );
}
程序运行后的输出结果是答案:B
A)0
B)1
C)2
D)4
题目解析:逻辑与”&&”的运算规则是两个运算对象均为真(非零)时,该逻辑表达式的值才为真(1),表达式”x>>2″中x的二进制数值为00100100,运算结果为1001,对应十进制数值为9,表达式”c<‘a'”的值为1,而9&&1的结果为1。
5. 以下语句的输出结果是
printf(“%d “, strlen(” “5ÿ “));答案:C
A)输出项不合法,无正常输出
B)14
C)5
D)8
题目解析:字符串” “5ÿ”中共有五个转义字符,分别是’ ‘、’ ” ‘、’5’、’ÿ’、”,各代表一个字符,strlen()计算的是字符串的实际长度(不包含结束标识符),所以输出结果为5。
6. 有以下程序
#include <stdio.h>
#include <string.h>
main()
{
char s[]=”Beijing”;
printf(“%d “, strlen(strcpy( s,”China”) ));
}
程序运行后的输出结果是答案:D
A)14
B)12
C)7
D)5
题目解析:strcpy(s,”China”)将字符串”China”覆盖s中的字符串,之后s[]={′C′,′h′,′i′,′n′,′a′,′′,′g′,′′},strlen()计算的是字符串的实际长度(不包含结束标识符),即统计的是第一个′′前字符个数,所以输出结果为5。
7. 有以下程序
#include <stdio.h>
#define N 2
#define M N+1
#define MUN (M+1)*M/2
main()
{
printf( “%d “, MUN );
}
程序运行后的输出结果是答案:B
A)6
B)8
C)5
D)9
题目解析:宏替换是使用宏名代替一个字符串,是一种机械、简单的置换,直接在替换处展开而不做语法检测,所以语句MUN=(M+1)*M/2=(N+1+1)*N+1/2=8。
8. 有以下程序
#include <stdio.h>
main()
{ int a=3 ,b=3;
printf(“%d “,a&b);
}
程序运行后的输出结果是答案:C
A)0
B)1
C)3
D)6
题目解析:按位与”&”运算符的运算规则是:只要对应的二进制位有一个为0时,结果就为0。一个数与自身的按位与运算结果不变,所以输出结果为3
9. 设有如下程序段
int a[8] = {0};
int b[] = {0};
char c[2] = {“A”, “B”};
char d = “AB”;
以下叙述正确的是答案:A
A)只有a, b的定义是合法的
B)只有a,b,c的定义是合法的
C)只有c的定义是合法的
D)a,b,c,d的定义都是合法的
题目解析:字符变量和字符数组中只能存放字符常量,不能存放字符串常量,所以变量c、d的定义不合法。
#include <stdio.h>
#include <string.h>
main()
{
printf(“%d “, strlen(“0 011”));
}
程序运行后的输出结果是答案:A
A)6
B)4
C)9
D)8
题目解析:字符串”0 011”中共有两个转义字符,分别是′′、′′,各代表一个字符,strlen()计算的是字符串的实际长度(不包含结束标识符),所以输出结果为6
11. 有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char a[] = “THIS”, *b = “OK”;
printf(“%d,%d,%d,%d “, strlen(a), sizeof(a), strlen(b), sizeof(b));
}
程序运行后的输出结果是答案:C
A)4,4,2,1
B)4,5,2,3
C)4,5,2,4
D)5,5,3,3
题目解析:strlen()计算的是字符串的实际长度(不包含结束标识符),所以strlen(a)的结果为4,strlen(b)的结果为2。sizeof(a)求的是字符数组a占用内存,包含字符串结束标识符′′,计算结果为5,sizeof(b)求的是一个指针占用字节数,在32位的计算机上规定一个指针变量占用的内存为32位,即4个字节,所以计算结果为4。
12. 有如下程序
#include <stdio.h>
int sum(int data)
{
static int init = 0;
return init += data;
}
main()
{
int i;
for (i=1; i<=5; i++)
printf(“%d,”, sum(i)); printf(” “);
}
程序运行后的输出结果是答案:B
A)1,2,3,4,5,
B)1,3,6,10,15,
C)0,0,0,0,0,
D)1,1,1,1,1,
题目解析:静态变量在定义时的初始化只运行一次,并且其值在程序运行过程中一直存在,所以函数sum()的作用是用静态变量init累加所有的调用sum()函数时传入的参数值。for循环中传入的参数为1,2,3,4,5,所以输出的结果为1,3,6,10,15。
13. 以下选项中正确的是答案:A
A)#define PI 3.14
B)#define int INT
C)##define eps 0.001
D)#DEFINE TRUE
题目解析:宏定义的一般形式为”#define 宏名 字符串(或数值)”,宏名的命名规则要符合用户标识符的命名规则。
14. 有如下程序
#include <stdio.h>
main()
{
int a = 8, b;
b = (a >> 2) % 2;
printf(“%d,%d “, a, b);
}
程序运行后的输出结果是答案:A
A)8,0
B)4,1
C)8,1
D)4,0
题目解析:变量a的二进制数为1000,1000>>2的结果为0010,对应十进制数值为2,而2%2结果为0,所以b为0,a值没有变化。
15. 有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char name[10] = “c-book”;
char* str = name;
printf(“%d,%d,%d,%d “, sizeof(name), strlen(name), sizeof(str), strlen(str));
}
程序运行后的输出结果是答案:D
A)11,6,1,6
B)11,6,11,6
C)10,7,1,7
D)10,6,4,6
题目解析:strlen()计算的是字符串的实际长度(不包含结束标识符),所以strlen(name)和strlen(str)的结果为均为6。sizeof(name)求的是字符数组a占用内存,数组a在定义时标明了维数为10,所以计算的结果为10;sizeof(str)求的是指针str占用字节数,在32位的计算机上规定一个指针变量占用的内存为32位,即4个字节,所以计算的结果为4。
16. 有如下程序
#include <stdio.h>
int disp(char* str)
{
while (*str) putchar(*str++);
return *str;
}
main()
{
printf(“%d “, disp(“NAME”));
}
程序运行后的输出结果是答案:A
A)NAME0
B)NAME
C)NAME
题目解析:函数disp()的功能是不断输出str指向的字符串中的字符,直到指针str指向该字符串的尾部′′,并返回当前字符的ASCII码值。main()函数中会输出该ASCII码值,字符′′的ASCII码值为0。
17. 有如下程序
#include <stdio.h>
main()
{
char *p, old_str[10] = “wind”;
int password;
scanf(“%d”, &password);
p = old_str;
while (*p)
{
printf(“%c”, *p + password);
p++;
}
printf(” “);
}
程序运行时,从键盘输入2<回车>,输出结果是答案:B
A)xjoe
B)ykpf
C)2222
D)wind
题目解析:这段代码的作用是给一个字符串加密,加密的方式是将原先字符串的每个字符的ASCII码加上password,即相当于在ASCII码表上取距离当前字符为password的字符作为加密后的字符。
18. 有如下程序
#include <stdio.h>
int* sum(int data)
{
static int init = 0;
init += data;
return &init;
}
main()
{
int i, *p;
for (i=1; i<=4; i++) sum(i);
p = sum(0);
printf(“%d “, *p);
}
程序运行后的输出结果是答案:C
A)1
B)0
C)10
D)15
题目解析:静态变量在定义时的初始化只运行一次,并且其值在程序运行过程中一直存在,所以函数sum()的作用是用静态变量init累加所有的调用sum()函数时传入的参数值。for循环中传入的参数为1,2,3,4,每次的计算结果为1,3,6,10。再次调用函数sun(0)时返回值为10。
19. 有如下程序
#include <stdio.h>
#define D(x) 4*x+1
main()
{
int i = 2, j = 4;
printf(“%d “, D(i+j));
}
程序运行后的输出结果是答案:D
A)9
B)25
C)12
D)13
题目解析:按位或运算”|”的运算规则是:只要对应的二进制位有一个为1时,结果就为1。13的二进制数为1101,5的二进制数为0101,1101|0101=1101,对应十进制数为13。
20. 设有以下定义
char s1[]=”0123″;
char s2[]={‘0′,’1′,’2′,’3’};
则以下叙述正确的是答案:C
A)数组s1的长度小于s2的长度
B)数组s1和s2完全等价
C)数组s1的长度大于s2的长度
D)数组s1和s2的长度相同
题目解析:字符数组s2的末尾字符不为′′,所以存放的并不是字符串,所以s2的字符个数为4,数组长度也为4;C语言中,若直接把一个字符串赋值给字符数组,系统会自动在末尾加上结束标识符′′并放置到该字符数组中,所以s1中的字符个数为5,数组长度也为5。
21. 以下选项中没有编译错误且ch能作为字符串使用的是答案:D
A)char ch[4]; ch=”abc”;
B)char ch[ ]={´a´,´b´,´c´};
C)char ch[3]=”abc”;
D)char *ch; ch=”abc”;
题目解析:通过赋初值的方式把一个字符串赋给字符数组必须要在字符串的末尾加上结束标识符′′,没有′′的不能判定该字符数组存放的是字符串,选项B)错误;用字符数组存放字符串的时候,字符数组的元素个数至少要比存放的字符串长度要多1,因为结束标识符也会被写入到字符数组中,选项C)错误;数组名为地址常量,不能对其进行赋值性操作,选项A)错误。
22. 有以下程序
#include <stdio.h>
void fun(int n)
{ int i;
if((i=n/10)!=0)
fun(i);
putchar( n%10+’0′);
}
main()
{ fun(256); }
程序运行后的输出结果是答案:C
A)2560
B)52
C)256
D)652
题目解析:函数fun()的功能利用递归调用的方式是将数字n的不同位提取出来并按照从高位到低位的顺序将各位的数字以字符的形式输出。
23. 有以下程序
#include <stdio.h>
#define FNA(x) x*x
#define FNB(x) x+x
main()
{ int a=2,b=4;
printf(“%d,%d “,FNA(FNB(a)),FNB(FNA(b)));
}
程序运行后的输出结果是答案:C
A)8,16
B)16,16
C)8,32
D)16,32
题目解析:宏替换是使用宏名代替一个字符串,是一种机械的、简单的置换,直接在替换处展开而不做语法检测,所以FNA(FNB(a))=FNB(a)*FNB(a)=a+a*a+a,结果为8,语句FNB(FNA(b))=FNA(b)+FNA(b)=b*b+b*b,结果为32
24. 在源程序的开始处加上预处理命令 #include <stdio.h> 的原因是答案:B
A)将stdio.h中标准输入输出函数的源程序插入到引用处,以便进行编译链接
B)stdio.h文件中包含标准输入输出函数的函数说明,通过引用此文件以便能正确使用printf、scanf等函数
C)将stdio.h中标准输入输出函数的二进制代码插入到引用处,以便进行编译链接
D)将stdio.h中标准输入输出函数链接到编译生成的可执行文件中,以便能正确运行
题目解析:预处理命令即预先需要处理好的东西,也即是printf、scanf等函数的使用。
25. 有以下程序
#include <stdio.h>
#define S(x) x/x*x
main( )
{ int k=6, j=3;
printf(“%d,%d “, S(k+j), S(j+k));
}
程序运行后的输出结果是答案:A
A)27,29
B)9,9
C)27,27
D)29,29
题目解析:S(k+j)=k+j/k+j*k+j=27.5,S(j+k)=j+k/j+k*j+k=29,输出为整数型,即27,29。
26. 若有定义
typedef int *T;
T c[20];
则以下选项中a的类型与上述定义中c的类型完全相同的是答案:A
A)int *a[20];
B)int **a[20];
C)int (*a)[20];
D)int a[20];
题目解析: typedef为类型定义符,作用是用”新类型名”代替”原类型名”,即为现有类型定义容易记忆的类型名。typedef int *T;将T换成下方定义的a[20]即可得出答案。
27. 若有定义
typedef int *T;
T *x[20];
则以下选项中a的类型与上述定义中x的类型完全相同的是答案:D
A)int *a[20];
B)int (*a)[20];
C)int *(*a)[20];
D)int **a[20];
题目解析:把T *x[20];这个中的值直接代入typedef int *T;即可知int **a[20];与上述定义完全相同。
28. 以下涉及字符数组、字符指针的程序段,没有编译错误的是答案:D
A)char line[];
line = “//////”;
B)char str1[7] = “prog.c”, str2[8];
str2 = str1;
C)char* name[6];
name = “Hello”;
D)char* str;
str = “C/C++”;
题目解析:字符数组中不能使用赋值操作符进行整体赋值(除了在定义时初始化),可使用strcpy或strncpy,故A)、B)、C)选项错误;D)选项中定义一个字符指针str,然后把一串字符的首地址赋给str,不会发生编译错误,故本题答案选D)。
29. 以下选项中正确的是答案:D
A)##DEFINE FALSE 0
B)#Define Eps 0.00001
C)#define int INT
D)#define PAI 3.14
题目解析:宏定义的一般形式为”#define 宏名 字符串(或数值)”,宏名的命名规则要符合用户标识符的命名规则。
30. 有以下程序
#include <stdio.h>
int* sum(int data)
{
static int init = 1;
init += data;
return &init;
}
main( )
{
int i, *p;
for (i=1; i<=3; i++) sum(i);
p = sum(1);
printf(“%d “, *p);
}
程序运行后的输出结果是答案:C
A)10
B)7
C)8
D)9
题目解析:静态变量在定义时的初始化只运行一次,并且其值在程序运行过程中一直存在,所以函数sum()的作用是用静态变量init累加所有的调用sum()函数时传入的参数值。for循环中传入的参数为1,2,3。每次的计算结果为1,3,6,再次调用函数sum(1)返回值为8。
31. 有以下程序
#include <stdio.h>
#define D(x) 2*x+3
main( )
{
int i = 1, j = 2;
printf(“%d “, D(i+j));
}
程序运行后的输出结果是答案:A
A)7
B)2
C)9
D)6
题目解析:D(i+j))=2*i+j+3=7。
32. 有以下程序
#include<stdio.h>
double fun1(double a[],int n)
{
int i;double sum=0.0;
for(i=0;i<n;i++)
sum+=a[i]/n;
return sum;
}
void fun2(double a[],int n,double *p,double *q)
{
int i;
*p=*q=a[0];
for(i=1;i<n;i++)
if(a[i]>*p) *p=a[i];
else if(a[i]<*q) *q=a[i];
}
void main()
{
double a[]={1,2,3,4,5};
double mx,mn,av;
av=fun1(a,5);
fun2(a,5,&mx,&mn);
printf(“%f %f %f “,av,mx,mn);
}
程序的运行结果是答案:D
A)3.000000 1.000000 5.000000
B)1.000000 5.000000 3.000000
C)5.000000 3.000000 1.000000
D)3.000000 5.000000 1.000000
题目解析:对于函数fun1,sum+=a[i]/n;和sum=sum+a[i]/n等价,依次将i=0,1,2,3,4;n=5代入可得,sum=3,每运行依次,sum值多一精度,即3.000000;对于函数fun2,其实是a[i]和a[0]之间做大小比较,把较小的赋值给*q,把较大的赋值给*p,i从1取值到5,较小的是1,较大的是5,即输出为5.000000和1.000000
33. 若有宏定义 :#define A_RECT(W,H) W*H 和以下程序段
int x=5,y=6,area1,area2;
area1= A_RECT((x-1),(y+1));
area2= A_RECT(x+3,y-1);
执行上述程序段后,变量area1和area2的值分别是答案:C
A)0 40
B)28 40
C)28 22
D)0 22
题目解析:area1=(x-1)*(y+1)=4*7=28,area2=x+3*y-1=5+3*6-1=22。
34. 有以下程序
#include<stdio.h>
void main()
{ unsigned char ch=0x0f;
unsigned char a , b;
a=ch>>2;
b=ch<<4;
printf(“%d %d “,a,b);
}
程序的运行结果是答案:A
A)3 240
B)3 15
C)3 16
D)3 -16
题目解析:>>右移位运算,<<左移位运算,输入中ch=0x0f(十六进制)=15(十进制)=1111(二进制),右移两位后变为0011(二进制)=3(十进制),左移4位后变为11110000(二进制)=240(十进制)
35. 以下叙述中正确的是答案:C
A)用static说明的变量是全局变量
B)系统默认auto变量的初值为0
C)register变量不能进行求地址运算
D)用register说明的变量被强制保留在CPU的寄存器中
题目解析:全局变量(extern)和用static修饰的局部变量都是静态变量,该变量是在编译时给变量分配存储空间,所占用存储单元直到程序结束时才释放。而自动变量(auto)和寄存器变量(register)为动态局部变量,只在程序执行到定义它的函数或者语句块时才为其分配内存。故本题答案选C)。
36. 有以下程序
#define Out(n) n%2==0 ? “%c” : “%d”
#include <stdio.h>
main()
{
int x;
for(x=65 ; x<69; x++)
printf(Out(x),x);
}
程序的运行结果是答案:A
A)65B67D
B)65666768
C)ABCD
D)A66C68
题目解析:先看定义的宏运算,n%2==0 ? “%c” : “%d”含义是如果n能整除2,则%c,否则%d;for循环中x取值为65,66,67,68,x=65时,宏返回值是%d,即按整数输出,x=66时,宏返回值是%c即按字母输出,ASCII码表中对应的是B,依次类推,得出结果。
37. 有以下程序
#include <stdio.h>
main()
{ char c1=022,c2=066;
c1&=c1; c2^=c2;
printf(“%o,%o “,c1,c2);
}
程序的运行结果是答案:A
A)22,0
B)0,66
C)0,0
D)22,66
题目解析:printf中的””引起来的为格式控制字符串,若为”O”或者”o”表示以八进制形式输出无符号整数;c2^=c2表示c2等于c2原来的值与c2按位异或;&= 是按位与之后赋值,相同位置均为1时结果为1,否则就是0。c1=022(八进制)=10010(二进制),进行按位与运算后仍为10010,即数值没有变 ;c2=066(八进制)=1000010(二进制),进行按位异或运算后,为0000000,即八进制数为0。
38. 有下列程序
#include <stdio.h>
#define S1(x,y) x*y
#define S2(x,y) (x)*(y)
main( )
{ int a=2, b=3;
printf(“%d,%d,%d”, S1(a+b,a+b), S1(b+a,a+b), S2(a+b,a+b));
}
程序执行后的输出结果是答案:C
A)11,11,25
B)11,10,11
C)11,10,25
D)25,25,25
题目解析:S1(a+b,a+b)=a+b*a+b=2+3*2+3=11, S1(b+a,a+b)=3+2*2+3=10, S2(a+b,a+b)=(2+3)*(2+3)=25,即输出为11,10,25。
39. 若有定义
typedef int *(*T)[10];
T a;
则以下与上述定义中a类型完全相同的是答案:C
A)int **a[10];
B)int *(*a[10]);
C)int *(*a)[10];
D)int *(a)[10];
题目解析: 很明显的一个选择,将T换成a答案就出来了
40. 有下列程序
#include <stdio.h>
main( )
{ int x=3, y=5, z1, z2;
z1 = y^x^y; z2 = x^y^x;
printf(“%d,%d “, z1, z2);
}
程序执行后的输出结果是答案:D
A)8,8
B)5,3
C)7,7
D)3,5
题目解析: ^的意思是异或,就是二进制的按位计算,相异为1,否则为0;z1=101^011^101=110^101=011=十进制的3,z2=011^101^011=110^011=101=十进制的5。
41. 以下涉及字符串数组、字符指针的程序片段,没有编译错误的是答案:C
A)char line[]; line = “=============”;
B)char* name[10], *str; name = “Hello World”;
C)char name[10], *str = “Hello World”;
D)char str1[10], str2[10] = “prog.c”; str1 = str2;
题目解析:定义字符数组如果没有在定义的同时初始化,一定要标明数组长度,字符串之间不能用赋值符号直接赋值,不可以用赋值语句给字符数组整体赋一串字符。
42. 有如下程序
#include <stdio.h>
#include <string.h>
main()
{
char* str = “0 0123”;
printf(“%d”, strlen(str));
}
程序运行后的输出结果是答案:B
A)8
B)7
C)4
D)6
题目解析: 表示的是转义字符,即回车换行,用strlen函数进行统计时是一个字符,用sizeof函数统计时是两个字符。本题总共是7的字符。
43. 下面关于编译预处理的命令行,正确的是答案:A
A)#define PI 3.14159
B)#define float FLOAT
C)define eps 0.0001
D)#DEFINE TRUE 1.0
题目解析:宏定义只是简单地宏替换,PI是符号常量。在程序中出现PI时,所有的PI都用3.14159代替。
44. 有如下程序
#include <stdio.h>
main()
{
int a = 8, b;
b = (a >> 3) * 8;
printf(“%d,%d”, a, b);
}
程序运行后的输出结果是答案:A
A)8,8
B)0,8
C)1,8
D)8,40
题目解析:十进制8转化为二进制数是1000,a>>3时将a的二进制数右移3位即等于二进制的0001,十进制数为1,b=1*8=8,所以输出的时候a,b都是8。
本章结束。。
123