admin 管理员组

文章数量: 1086019


2024年5月21日发(作者:distinction misses the point)

第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) =c;=b;

B) =q;=;

C) p->next=&c;q->next=p->next;

D) (*p).next=q;(*q).next=&b;

考点:向链表插入结点。

分析:答案A中,是一个指针变量,而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.2fn",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

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("%dn",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

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

union un

{ int i;

char c[2];

};

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%dn",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;

char sex;

float score[4];

}stu;

main( )

{ stu a[5];

printf("%dn",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,%fn",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("%dn",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=&

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) =1976

C) =1976 D) =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

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("%dt",++p->n);

printf("%dt",(++p)->n);

printf("%dn",++(*p->m));

}

A) 101 200 21 B) 101 20 30

C) 200 101 21 D) 101 101 10

8.以下程序的运行结构是 。

#include

main( )

{ union

{ long a;

int b;

char c;}m;

printf("%dn",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("%dn",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】 ;

}

是一个链表的头指针,该链表结点的data域由小到大排列。函数insert

(head,data)将一个值为data的新结点插入到链表中,且保证插入后的链表

仍然是有序的。请填空:

#include

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

current==head

3】【


本文标签: 变量 链表 结构 指针 类型