第9章编译预处理
1.以下程序的输出结果是()
A、9B、6C、36D、18
#define f(x) x*x
main( )
{ int a=6,b=2,c;
c=f(a) / f(b);
printf("%d n",c);
}
答案:C
注解:宏定义在编译阶段进行宏展开,则c=f(a)/f(b)宏展开后为c=a*a/b*b,将变量a和b的值分别代入,即可算出c的值36。
2.下列程序执行后的输出结果是()
A、6B、8C、10D、12
#define MA(x) x*(x-1)
main( )
{ int a=1,b=2;printf("%d n",MA(1+a+b));}
答案:B
注解:MA(1+a+b)宏展开后为1+a+b*(1+a+b-1),将a和b的值代入,计算出表达式的值为8。
3.有如下程序
#define N 2
#define M N+1
#define NUM 2*M+1
main( )
{ int i;
for(i=1;i<=NUM;i++) printf("%dn",i);
}
该程序中的for循环执行的次数是()
A、5B、6C、7D、8
答案:C
注解:M宏展开后为2+1=3,NUM宏展开后为2*3+1=7,循环控制条件i的变化是从1递增到7,所以循环执行的次数是7次。
4.以下程序的输出结果是()
A、16B、2C、9D、1
#define SQR(X) X*X
main( )
{ int a=16,k=2,m=1;
a/=SQR(k+m)/SQR(k+m);
printf("%dn",a);
}
答案:B
注解:SQR(k+m)宏展开后为k+m*k+m,所以表达式SQR(k+m)/SQR(k+m)的宏展开后为k+m*k+m/k+m*k+m,值代入即为2+1*2+1/2+1*2+1=7,a/=SQR(k+m)/SQR(k+m)可表示为a/=7,则a的值为2。
填空:
1. 以下程序的输出结果是_____________。
#define MAX(x,y) (x)>(y)?(x):(y)
main()
{ int a=5,b=2,c=3,d=3,t;
t=MAX(a+b,c+d)*10;
printf("%dn",t);
}
答案:MAX(a+b,c+d)*10宏展开后为(a+b)>(c+d)?(a+b):(c+d)*10,条件表达式的条件成立,取a+b的值7,所以输出为7。
第10章指针
1.以下程序的输出结果是(b)
A、6B、6789C、'6'D、789
main( )
{ chara[10]={'1','2','3','4','5','6','7','8','9',0},*p;
int i;
i=8;
p=a+i;
printf("%sn",p-3);
}
答案:B
注解:指针变量p指向一维数组a的第9个元素,输出时p指针向前移动3个单位再输出,从字符'6'开始输出,直到最后一个结束符。
2.以下程序的运行结果是()
A、运行后报错B、66C、612D、5 5
#include "stdio.h"
main( )
{int a[ ]={1,2,3,4,5,6,7,8,9,10,11,12,};
int *p=a+5, *q=NULL;
* q=*(p+5);
printf("%d %d n",*p,*q);
}
答案:A
注解:指针变量q
3.若已定义:int a[9],*p=a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是( )
A、p+1B、a+1C、a++D、++p
答案:C
注解:a++这种表达方式是错误的,数组名a是常量,不能进行自增运算。
4.若有说明:long*p,a;则不能通过scanf语句正确给输入项读入数据的程序段是()
A、*p=&a; scanf("%ld",p);
B、p=(long *)malloc(8); scanf("%ld",p);
C、scanf("%ld",p=&a);
D、scanf("%ld",&a);
答案:A
注解:选项a中的赋值表达式应改为p=&a才是正确的赋值方式。
5.下面程序把数组元素中的最大值放入a[0]中,则在if语句中的条件表达式应该是()
A、p>aB、*p>a[0]C、*p>*a[0]D、*p[0]> *a[0]
main( )
{ int a[10]={6,7,2,9,1,10,5,8,4,3},*p=a,i;
for(i=0;i<10;i++,p++)
if(________) *a=*p;
printf("%d",*a);
}
答案:B
注解:数组的最大值是放在a[0]中,用a[0]和后面的每一个元素做比较,所以if语句的条件表达式是*p与a[0](或*a)作比较,即可为*p>*a或*p>a[0]。
6.以下程序的输出结果是()
A、4 2 11B、0 0 08C、4 6 78D、8 8 8 8
main( )
{ char *s="12134211"; int v[4]={0,0,0,0},k,i;
for(k=0;s[k];k++)
{ switch(s[k])
{ case '1':i=0;
case '2':i=1;
case '3':i=2;
case '4':i=3;
}
v[i]++;
}
for(k=0;k<4;k++) printf("%d",v[k]);
}
答案:B
注解:在for循环中,循环执行到字符串的结束标志0结束,在选择开关语句switch中,不管s[k]的值为何值,最后i的值始终为3,因为在case子句后没有break,所以一直是v[3]在自增,v[3]的值和循环次数一致为8。
7.以下程序的输出结果是()
A、AfghdEFGB、AbfhdC、AfghdD、Afgd
#include"string.h"
main( )
{ char *p1,*p2,str[50]="ABCDEFG";
p1="abcd"; p2="efgh";
strcpy(str+1,p2+1); strcpy(str+3,p1+3);
printf("%s",str);
}
答案:D
注解:strcpy(str+1,p2+1);取字符串"efgh"的一部分"fgh"放置到数组str中代替从第二个字符向后的所有内容,则数组str中内容为"Afgh",语句strcpy(str+3,p1+3);取字符串"abcd"的"d"放置到数组str中代替从第四个字符向后的内容,则数组str中内容为"Afgd"。
8.若已定义:int a[ ]={0,1,2,3,4,5,6,7,8,9},*p=a,i;
其中0<I<9,则对a数组元素不正确的引用是()
A、a[p-a]B、*(&a[i])C、p[i]D、a[10]
答案:D
注解:对数组元素的引用下标是从0到数组长度减1,所以a数组元素为a[0]到a[9],只有选项D超出了范围。
9.下列程序执行后的输出结果是()
A、6B、7C、8D、9
void func(int *a,int b[])
{ b[0]=*a+6;}
main( )
{ int a,b[5];
a=0;b[0]=3;
func(&a,b); printf("%d n",b[0]);
}
答案:A
注解:func函数的参数传递的是地址,所以在函数体中改变数组元素b[0]的值,则主函数中b[0]的值也发生改变,b[0]的值为6。
10.下列程序的输出结果是()
A、4B、6C、8D、10
int b=2;
int func(int *a)
{ b += *a;
return(b);}
main( )
{ int a=2,res=2;
res+= func(&a);
printf("%d n",res);
}
答案:B
注解:在func函数体中,使用的是全局变量b的值2和实参传递的值2,返回两者的和4,再加上变量res的值2,最后变量res的值为6。
11.设已有定义:char *st="how are you";下列程序段中正确的是(c)
A、char a[11],*p;strcpy(p=a+1,&st[4]);
B、 char a[11];strcpy(++a,st);
C、 char a[11];strcpy(a,st);
D、char a[],*p;strcpy(p=&a[1],st+2);
答案:C
注解:strcpy(s1,s2)是字符串拷贝函数,表示将字符串s2中的内容复制到s1中,s2可以是字符变量或常量,s1是字符变量,且长度应该大于等于s2的长度。
12.有如下程序段
int *p,a=10,b=1;
p=&a;a=*p+b;
执行该程序段后,a的值为( )
A、12B、11C、10D、编译出错
答案:B
注解:指针变量p指向整型变量a,表达式*p+b即是表示a+b,所以执行应该程序段后,a的值为11。
13.对于基类型相同的两个指针变量之间,不能进行的运算是( c )
A、<B、=C、+D、-
答案:C
14.以下函数返回a所指数组中最小的值所在的下标值
fun(int *a,int n)
{ int i,j=0,p;
p=j;
for(i=j;i<n;i++)
if(a[i]<a[p]) ;
return(p);
}
在下划线处应填入的是()
A、i=pB、a[p]=a[i]C、p=jD、p=i
答案:D
注解:根据题意,变量p中存放的是最小值所在的下标值,则若判断a[i]<a[p]成立,就应该让p中保留较小数所在的下标值。
15.有以下函数
char fun(char *p)
{ return p;}
该函数的返回值是(c)
A、无确切的值B、形参p中存放的地址值
C、一个临时存储单元的地址D、形参p自身的地址值
答案:B
注解:函数fun的形参是字符指针变量,所以return p;的返回值是p中存放的地址值。
16.有如下说明
int a[10]={1,2,3,4,5,6,7,8,9,10},*P=a;
则数值为9的表达式是(b)
A、*P+9 B、*(P+8)C、*P+=9D、P+8
答案:B
注解:数值9是数组中的第9个元素,它可以用a[8],*(a+8),P[8],*(P+8)表示。
17.有如下程序
main( )
{ char s[]="ABCD",*p;
for(p=s+l;p<s+4;p++) printf("%sn",p);
该程序的输出结果是()
A、ABCDB、AC、BD、BCD
BCD B C CD
CD CDD
DD
答案:D
注解:程序执行过程如下:循环初始条件,字符指针变量p先指向数组s的第二个元素,输出从B开始的全部字符BCD;第二次执行循环,p指向数组s的第三个元素,输出从C开始的全部字符CD;第三次执行循环,p指向数组s的第四个元素,输出从D开始的全部字符D。
18.下列程序段的输出结果是( )
A、2 1 43B、1 2 12C、1 2 34D、2 1 1 2
void fun(int *x,int *y)
{ printf("%d %d",*x,*y); *x=3; *y=4;}
main( )
{ int x=1,y=2;
fun(&y,&x);
printf("%d %d",x,y);
}
答案:A
注解:函数fun的两个参数是指针类型,在调用过程中,把实参y的地址传给形参x,把实参x的地址传给形参y,则在执行函数体时,输出的值为2和1,同时改变了实参x和y的值,x值变为3,y的值变为4,函数执行结束返回主函数,输出的值是改变后的值3和4。
19.下列程序的输出结果是(c)
A、非法B、a[4]的地址C、5D、3
main( )
{ char a[10]={9,8,7,6,5,4,3,2,1,0},*p=a+5;
printf("%d",*--p);}
答案:C
注解:指针变量p指向数组a的第6个元素,即a[5],则输出的表达式*--p的值,先计算--p,p指向前一个元素a[4],*--p即是取a[4]的值,所以输出的值为a[4]的值,为5。
20.下面程序的输出结果是(c)
A、0B、1C、10D、9
main()
{ int a[ ]={1,2,3,4,5,6,7,8,9,0},*p;
p=a;
printf("%dn",*p+9);}
答案:C
注解:指针变量p指向数组a的第一个元素a[0],表达式*p+9即是a[0]+9,则值为10。
21.若定义:inta=511,*b=&a;,则printf("%dn",*b);的输出结果为(d)
A、无确定值B、a的地址C、512D、511
答案:D
注解:指针变量p指向变量a,则输出b所指向的单元的值即是a的值。
22.以下程序的输出结果是()
char cchar(char ch)
{if(ch>='A'&&ch<='Z')ch=ch-'A'+'a';
return ch;
}
main( )
{chars[]="ABC+abc=defDEF",*p=s;
while(*p)
{*p=cchar(*p);
p++;
}
printf("%sn",s);
}
A、abc+ABC=DEFdefB、abc+abc=defdef
C、abcaABCDEFdefD、abcabcdefdef
答案:B
注解:函数cchar()的功能是将形参ch对应的字母转换为小写字母,在主函数中,指针变量p指向字符数组s的首地址,while循环从数组的字符'A'到'F',依次调用函数进行转换,故答案为C。
23.以下程序调用findmax函数返回数组中的最大值
findmax(int *a,int n)
{int *p,*s;
for(p=a,s=a;p-a<n;p++)
if() s=p;
return(*s);
}
main( )
{intx[5]={12,21,13,6,18};
printf("%dn",findmax(x,5));}
在下划线处应填入的是()
A、p>sB、*p>*sC、a[p]>a[s]D、p-a>p-s
答案:B
注解:findmax()函数的功能是找出数组中的最大值,在for循环中,s表示最大值的地址,指针变量p是移动指针,遍历数组的所有元素,与最大值做比较,取值的格式是*p与*s,然后做比较。
24.以下程序的输出结果是()
#include<stdio.h>
#include<string.h>
main( )
{char b1[18]="abcdefg",b2[8],*pb=b1+3;
while(--pb>=b1) strcpy(b2,pb);
printf("%dn",strlen(b2));
}
A、8B、3C、1D、7
答案:D
注解:初始条件,指针变量pb指向数组b1的第四个元素b1[3],循环的条件--pb>=b1成立(此时pb指向数组b1的第三个元素b1[2]),执行循环体,将指针变量pb所指单元向后的内容赋给数组b2,一直执行到指针变量pb指向数组b1的首地址,即将数组b1中的所有字符都赋给数组b2,则strlen(b2)和strlen(b1)相等。
填空题
1.mystrlen函数的功能是计算str所指字符串的长度,并作为函数值返回。请填空:
int mystrlen(char *str)
{int i;
for(i=0;(1) != ' ';i++) ;
return((2) );
}
答案:(1)*(str+i)(2) i
注解:str所指字符串,从第一个字符计算,直到最后一个结束标志,字符个数由变量i统计。
2. 以下程序运行后的输出结果是_________________
main( )
{ char s[ ]="9876",*p;
for ( p=s ; p<s+2 ; p++)printf("%sn", p);
}
答案:9876
876
注解:在循环的初值表达式中,字符指针变量p指向数组s,条件p<s+2成立,则输出9876,指针变量p自增1,指向数组s的第二个元素(即p=s+1),条件p<s+2成立,则在第二行输出876,指针变量p自增1,指向数组s的第三个元素(即p=s+2),此时条件p<s+2不成立,则退出循环,输出结束。
3.以下程序的输出结果是_____________。
main( )
{ int arr[ ]={30,25,20,15,10,5}, *p=arr;
p++;
printf("%dn",*(p+3));
}
答案:10
注解:指针变量p指向数组arr,先指向数组的首地址,执行p++后,p指向数组的第二个元素arr[1],p+3指向数组的第五个元素arr[4],则输出的值为10。
4.若有以下定义,则不移动指针p,且通过指针p引用值为98的数组元素的表达式是_____________。
int w[10]={23,54,10,33,47,98,72,80,61}, *p=w;
答案:
注解:98是数组w中的第6个元素,即w[5],指针变量p指向数组的首地址,则w[5]用p表示为*(p+5)。
第11章结构体
1.有如下定义( )
struct person{char name[9]; int age;};
struct person class[10]={"Johu",17,"Paul",19,"Mary",18,"Adam",16};
根据上述定义,能输出字母M的语句是(d )
A、prinft("%cn",class[3].mane);
B、 pfintf("%cn",class[3].name[1]);
C、 prinft("%cn",class[2].name[1]);
D、printf("%cn",class[2].name[0]);
答案:D
注解:字母M是在定义的结构体类型的数组class中的第三个元素的第一个成员的第一个字母,首先数组class的第三个元素的正确表示是class[2],它的第一个成员的正确表示是class[2].name,第一字母的正确表示则是class[2].name[0]。
2.设有以下说明语句
struct ex
{ int x;float y;char z;}example;
则下面的叙述中不正确的是(b)
A、struct是结构体类型的关键字B、example是结构体类型名
C、x,y,z都是结构体成员名D、struct ex是结构体类型名
答案:B
注解:example是结构体类型的变量名,struct ex才是结构体类型名。
3.以下程序的输出是(c)
A、10B、11C、51D、60
struct st
{ int x;int *y;} *p;
int dt[4]={ 10,20,30,40 };
struct st aa[4]={50,&dt[0],60,&dt[0],60,&dt[0],60,&dt[0]};
main( )
{ p=aa;
printf("%dn",++(p->x));
}
答案:C
注解:结构体指针变量p指向数组aa,表达式p->x的值为数组aa的第一个元素aa[0]的第一个成员,即aa[0].x的值50,则表达式++(p->x)的值为51。
4.若有下面的说明和定义:
struct test
{int m1;char m2;float m3;
union uu{char u1[5];in
}myaa;
则sizeof(struct test)的值是()
A、12B、16 t u2[2];}ua;
C、14D、9
答案:A
注解:sizeof(structtest)是计算结构体变量所占的字节数,整型成员m1占2个字节,字符型m2占1个字节,浮点型m3占4个字节,共用体成员ua占5个字节,则sizeof(structtest)的值为12。
填空题
1.以下定义的结构体类型拟包含两个成员,其中成员变量info用来存入整型数据;成员变量link是指向自身结构体的指针,请将定义补充完整。
Struct node
{int info;
________struct node*_____ link;
}
答案:struct node *
2. 设有如下宏定义
#define MYSWAP(z,x,y){z=x;x=y;y=z}
以下程序段通过宏调用实现变量a、b内容交换,请填空:
float a=5,b=16,c;
MYSWAP(_______,a,b);
答案:c
注解:将宏MYSWAP(c,a,b)展开,即是{c=a;a=b;b=c},实现了a、b内容交换。
3. 设有以下结构类型说明和变量定义,则变量a在内存所占字节数是_______22_____。
Struct stud
{ char num[6];
int s[4];
double ave;
} a,*p;
答案:22
注解:变量a在内存所占的字节数为6+4*2+8=22。