C语言各章节单元测试题及答案——结构体与共用体

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第9章结构体与共用体
9.1典型考试题剖析
9.1.1选择题
【例1】若指针p已经正确定义,要使p指向两个连续的整型动态存储单元,不正确的语句是。

A) p=2*(int *)malloc(sizeof(int)); B) p=(int
*)malloc(2*sizeof(int));
C) p=(int *)malloc(2*2); D) p=(int
*)calloc(2,sizeof(int));
✧考点:动态存储分配函数。

✧分析:根据动态存储分配函数malloc和calloc的函数原型可以知道,
calloc函数的调用形式为:void * calloc(unsigned n,unsigned size);
表示在动态存储区中分配n个长度为size的连续空间,函数返回一个指
向分配域起始地址的指针,因此答案D是正确的。

malloc函数的调用形
式为:void * malloc(unsigned int size);表示是在内存的动态存储区
分配一个长度为size的连续空间,并返回一个指向分配域起始地址的指
针,答案B和C中malloc的参数分别为:2*(sizeof(int))和2*2,
都是整型数,因此调用形式正确。

答案A中(int *)malloc(sizeof(int))
的返回值为一个地址值,将地址的值乘以2是没有意义的。

✧答案:A
【例2】若有以下说明和定义:
struct test
{ int m1; char m2; float m3;
union uu
{ char u1[5]; int u2[2]; }ua;
}myaa;
则sizeof(struct test)的值是。

A) 12 B) 16 C) 14 D) 9
✧考点:结构体类型和共用体类型所占内存的字节数。

✧分析:sizeof(struct test)的功能是求结构体类型test所占用的内
存字节数。

它应该等于结构体每个成员所占的字节数之和。

m1为int型,占2字节,m2为char型,占1字节,m3为float型,占4字节,接下
来是一个共用体类型uu,共用体所占的字节数应该等于成员中最长者所
占的字节数,u1占5字节,u2占4字节,那么该共用体类型应该占用5
字节,所以2+1+4+5=12。

✧答案:A
【例3】若有以下定义:
struct link
{ int data;
struct link *next;
}a,b,c,*p,*q;
且变量a和b之间已经有如右图所示的链表结构:指针p指向变量a,q指向变量c。

能够把c插到a和b之间,并形成新的链表的语句组是。

A) a.next=c;c.next=b;
B) p.next=q;q.next=p.next;
C) p->next=&c;q->next=p->next;
D) (*p).next=q;(*q).next=&b;
✧考点:向链表插入结点。

✧分析:答案A中,a.next是一个指针变量,而c是一个结构体变量,
二者不能互相赋值。

答案B错误在于p和q都是指针变量,引用时只有
p->next或(*p).next两种形式才是正确的。

答案C中的第一句将变量a
的next指针指向了变量c,但是第二句却没有将c的next指针指向b,而是指向c本身。

答案D是先把结构体变量a的next指针指向c,再使
c的next指针指向b。

✧答案:D
【例4】设有以下说明语句:
typedef struct
{ int n;
char ch[8];
}per;
则下面叙述正确的是。

A) per是结构体变量名 B) per是结构体类型名
C) typedef是结构体类型 D) struct是结构体类型名
✧考点:用typedef定义新类型。

✧分析:根据概念,typedef的作用是声明新的类型名来代替已有的类型
名,因此只有答案B是正确的。

✧答案:B
【例5】有以下程序:
struct stu
{ char[10];
float score[3];
};
main()
{
struct stu s[3]={{"20021",90,95,85},
{"20022",95,80,75},
{"20023",100,95,90}}, *p=s;
int i;
float sum=0;
for(i=0;i<3;i++)
sum=sum+p->score[i];
printf("%6.2f\n",sum);
}
程序运行后的输出结果是。

A) 260.00 B) 270.00 C) 280.00 D) 285.00
✧考点:结构体变量成员的引用。

✧分析:本题中,s为一个结构体数组,p为结构体指针。

语句p=s使p
指向数组s的第一个元素即s[0]。

for循环的作用是将p所指向的单元累加到变量sum中,作用相当于相当于语句s[0].score[0]+
s[0].score[1]+ s[0].score[2]。

✧答案:B
【例6】有以下程序
#include <stdlib.h>
struct node
{ int num;
struct node *next;};
main()
{ struct node *p,*q,*r;
p=(struct node *)malloc(sizeof(struct node));
q=(struct node *)malloc(sizeof(struct node));
r=(struct node *)malloc(sizeof(struct node));
p->num=10; q->num=20; r->num=30;
p->next=q;
q->next=r;
printf("%d\n",p->num+p->next->num);
}
程序运行后的输出结果是。

A) 10 B) 20 C) 30 D) 40
✧考点:指向结构体变量的指针和结构体成员引用。

✧分析:程序中建立了一个链表,含有三个结点p、q、r,语句
p->next=q;q->next=r;将三个结点连接起来,如图所示。

✧答案:D
【例7】下面程序的输出结果为。

#include <stdio.h>
main( )
{ struct st
{ int x;
unsigned a:2;
unsigned b:2;
}st1,st2;
printf("\n%d",sizeof(struct st));
}
A) 2.5 B) 3 C) 2 D) 不确定
✧考点:位段有关知识。

✧分析:在本例中涉及到位段定义的知识。

位段又称位域或位字段,此种
定义可以使若干个结构体成员共用一个或几个字节,其中每个成员占用若干二进制位。

位段定义和普通结构体定义类似,只是每个成员附加二进制位数说明,如:
struct stru
{ unsigned a :2;
unsigned b :4;
unsigned :0;
unsigned d :2;
};
其中位数为0的无名字段的含义是跳过该字节剩余的位不用,所以上述中stru所占的字节数为2。

注意:位域成员通常没有独立的存储单元,因此诸如&st1.a,&st2.b之类对位域成员取地址的运算是非法的。

另外,位域成员只能是int或unsigned类型,其它类型都是非法的,而且位域成员也不能排成数组,如:unsigned c[2]:2是错误的。

本例中,a和b各占用2个二进制位,不够一个字节,系统将边界调整为整数,加上int型变量x占用的2个字节,共占用3字节。

✧答案:B
【例8】下述程序的执行结果是。

#include <stdio.h>
union un
{ int i;
};
void main( )
{ union un x;
x.c[0]=10;
x.c[1]=1;
printf("\n%d",x.i);
}
A) 266 B) 11 C) 265 D) 138
✧考点:本例考察的是共用体的特性。

✧分析:int型变量i和字符数组c共用2个字节的存储单元,通常c[0]
位于低字节,c[1]位于高字节。

因此,x.i=x.c[1]*256+c[0]=266,正确答案为A。

通过本例我们知道,共用体可以实现将一个数据的各个字节拆分出来单独使用。

✧答案:A
【例9】下面程序的输出是。

main()
{ enum team { my,your=4,his,her=his+10};
printf("%d%d%d%d\n",my,your,his,her); }
A) 0 1 2 3 B) 0 4 0 10 C) 0 4 5 15 D) 1 4 5 15
✧考点:枚举类型数据的性质。

✧分析:枚举类型定义后的枚举元素表中的元素值排列顺序依次为0,1,
2…,若其中某一元素给定初值,则其后的元素值依次递增。

✧答案:C
【例10】以下对枚举类型名的定义中正确的是。

A) enum a={one,two,three};
B) enum a {one=9,two=-1,three};
C) enum a={"one","two","three"};
D) enum a {"one","two","three"};
✧考点:枚举类型的定义。

✧分析:根据枚举类型的定义形式知道,只有答案B的形式是正确的。

✧答案:B
9.1.2填空题
【例1】下面程序的运行结果为。

typedef union student
{ char name[10];
long sno;
float score[4];
}stu;
main( )
{ stu a[5];
printf("%d\n",sizeof(a));
}
✧考点:结构体变量所占内存的长度。

✧分析:本题中a是一个共用体数组,题目最终要求出数组a所占的内存
字节数,由于数组a包含5个元素,因此它所占的内存字节数为:每个
元素所占的字节数*5。

而每个元素都是共用体类型变量,它们的长度等
于分量中长度最长的变量,显然score数组占16字节是最长的。

因此该
题的结果为:16*5=80。

✧答案:80
【例2】以下程序完成链表的输出,请填空。

void print(head)
struct stu *head;
{ struct stu *p;
p=head;
if( 【1】 )
do
{ printf("%d,%f\n",p->num,p->score);
p=p->next;
}while( 【2】 );
}
✧考点:链表操作。

✧分析:p是指向链表结点的指针变量,输出过程中每输出一个结点的内
容之后,就向后移动一个位置,当p指向NULL时输出结束,两处空白处
均为判断链表是否结束的语句,其中第一空判断链表是否为空表。

✧答案:【1】p!=NULL 【2】p!=NULL
【例3】已知指针变量head指向单链表表头,下面程序用来统计链表中各个结点的数据项之和,请填空。

struct link
{ int data;
struct link *next;
};
main()
{ int k;
struct link *head;
k=sum(head);
printf("%d\n",k);
}
sum( 【1】 )
{ struct link *p;
int s;
s=head->data;
p=head->next;
while(p)
{ s+= 【2】 ;
p=p->next;
}
return(s);
}
✧考点:链表操作。

✧分析:求和函数sum的形参应该接收实参传过来的单向链表头结点的地
址,所以应该为一个指针变量,求和语句应该填入的是用指针变量p引
用结构体的数据成员。

✧答案:【1】struct link *head 【2】p->data或(*p).data
【例4】下面程序的输出结果是。

main()
{ enum abc{ green=3,red };
char *clr[ ]={"red","blue","yellow","black","white","green"};
printf("%s and ",clr[green]);
printf("%s",clr[red]);
}
✧考点:枚举类型数据。

✧分析:字符型指针数组clr中存放的是6个字符串的首地址,因枚举元
素是常量,所以printf语句中的输出项clr[green]、clr[red]就是
clr[3]、clr[4]即"black"和"white"的首地址。

✧答案: black and white
9.2自测练习与参考答案
9.2.1选择题
1.有以下定义和语句:
struct student
{ int age;
int num; };
struct student stu[3]={{1001,20},{1002,19},{1003,21}};
main()
{ struct student *p;
p=stu;
…… }
则以下不正确的引用是。

A) (p++)->num B) p++ C) (*p).num D) p=&stu.age
2.有以下结构体定义:
struct example
{ int x;
int y; }v1;
则正确的引用或定义是。

A) example.x=10 B) example v2; v2.x=10;
C) struct v2; v2.x=10; D) struct example v2={10};
3.对于如下结构体定义,若对变量person的出生年份进行赋值,正确的赋值是。

struct date
{ int year,month,day;
};
struct worklist
{ char name[20];
char sex;
struct date birth;
}person;
A) year=1976 B) birth.year=1976
C) person.birth.year=1976 D) person.year=1976
4.根据下述定义,可以输出字符'A'的语句是。

struct person
{ char name[11];
struct
{ char name[11];
int age;
}other[10];
};
struct person man[10]={ {"Jone",{"Paul",20}},{"Paul",{"Mary",18}},
{"Mary",{"Adam",23}},{"Adam",{"Jone",22}}
};
A) printf("%c",man[2].other[0].name[0]); B)
printf("%c",other[0].name[0]);
C) printf("%c",man[2].(* other[0])); D)
printf("%c",man[3].name);
5.若有以下程序段:
struct st
{ int n;
struct st *next; };
struct st a[3]={5,&a[1],7,&a[2],9, '\0'} ,*p=a;
则值为6的表达式为。

A) p++->n B) p->n++ C) (*p).n++ D) ++p->n
6.对于以下定义,不正确的叙述是。

union data
{ int i;
char c;
float f;}a,b;
A) 变量a所占的内存长度等于成员f的长度
B) 变量a的地址和它的各成员地址都是相同的
C) 不能对变量a赋初值
D) 可以在定义的时候对a初始化
7.下述程序运行结果为。

#include <stdio.h>
struct st
{ int n;
int *m;
}*p;
void main()
{ int d[5]={10,20,30,40,50};
struct st arr[5]={100,d,200,d+1,300,d+2,400,d+3,500,d+4};
p=arr;
printf("%d\t",++p->n);
printf("%d\t",(++p)->n);
printf("%d\n",++(*p->m));
}
A) 101 200 21 B) 101 20 30
C) 200 101 21 D) 101 101 10
8.以下程序的运行结构是。

#include <stdio.h>
main( )
{ union
{ long a;
int b;
char c;}m;
printf("%d\n",sizeof(m));}
A) 2 B) 4 C) 6 D) 7
9.若要利用下面的程序段使指针变量p指向一个存储整型变量的存储单元,则在空格中应填入的内容是。

int *p;
p= malloc(sizeof(int));
A) int B) int * C) (* int) D) (int *)
10.执行下述语句后的结果是。

enum weekday {sun,mon=3,tue,wed, thu};
enum weekday day;
day=wed;
printf("%d\n",day);
A) 5 B) 3 C) 4 D) 编译时出错
9.2.2填空题
1.若已定义:
struct num
{ int a;int b;
float f;
}n={1,3,5.0};
struct num *pn=&n;
则表达式pn->b/n.a*++pn->b的值是【1】。

表达式(*pn).a+pn ->f的值是【2】。

2.对于图中所示的存储结构,每个结点含有三个域,front是指向前一个结点的指针域,data是指向字符串的指针域,next是指向下一个结点的指针域,请填空晚成此结构的类型定义和说明。

struct link
{ 【1】 ;
char *data;
【2】 ;
}*head;
3.以下程序段的功能是统计链表中结点的个数,first为指向第一个结点的指针(链表不带头结点),请在中填入正确的内容。

struct link
{ char data;
struct link *next;
}
……
struct link *p,*first;
int c=0;
p=first;
while( 【1】 )
{ 【2】 ;
p= 【3】 ;
}
4.head是一个链表的头指针,该链表结点的data域由小到大排列。

函数insert (head,data)将一个值为data的新结点插入到链表中,且保证插入后的链表仍然是有序的。

请填空:
#include <stdio.h>
typedef struct node
{ int data;
struct node *next;
}node;
node *insert(node *head,int data)
{ node *new,*front,*current;
current=head;
while((current!=NULL)&&( 【1】 ))
{ front=current;
current=current->next;
}
new= 【2】 ;
new->data=data;
new->next=current;
if( 【3】 )
head=new;
else
front->next=new;
return head;
}
9.2.3参考答案
一.选择题:
1.D 2.D 3.C 4.A 5.D
6.C 7.A 8.C 9.D 10.A
二.填空题:
1.【1】12 【2】6.0
2.【1】struct link *front 【2】struct link *next
3.【1】p!=NULL 【2】c++ 【3】p->next
4.【1】current->data<data 【2】(node *)malloc(sizeof(node)) 【3】current==head。

相关文档
最新文档