第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;
sizeof结构体大小struct link *next;
}a,b,c,*p,*q;
且变量a和b之间已经有如右图所示的链表结构:指针p指向变量a,q指向变量c。能够把c插到a和b之间,并形成新的链表的语句组是 。
A) a.next==b;
B) p.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是错误的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论