结构体和共用体
- 格式:doc
- 大小:461.00 KB
- 文档页数:13
结构体与共用体笔记定义结构体C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体(structre)。
在其他一些高级语言中称为“记录”.定义后的结构体类型和系统提供的标准类型(如int, char, float, double 等)具有相似的作用,都可以用来定义变量,只不过int等类型是系统已声明的,而结构体类型是由用户根据需要在程序中指定的。
定义一个结构体类型的一般形式为:struct 结构体名{ 成员表列};注意:1.结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如struct Student) ,结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。
上面的结构体声明中Student就是结构体名(结构体标记)。
2.花括号内是该结构体所包括的子项,称为结构体的成员。
“成员表列"(member list)也称为“域表”(field list),成员表列由若干个成员组成,每一个成员是结构体中的一个域。
对每个成员也必须作类型说明,其形式为:类型说明符成员名;成员名的命名应符合标识符的书写规定。
例如:struct stu{int num;char name[20];char sex;float score;};3.一个结构体的成员可以属于另一个结构体类型(嵌套)。
例如:struct Date //声明一个结构体类型struct Date{ int month;//月int day;//日int year;//年}struct Student//声明一个结构体类型struct Student{ int num;char name[20];char sex;int age;struct Date birthday;//成员birthday属于struct Date 类型char addr[30];};结构体类型变量1.定义结构体类型变量说明结构变量有以下三种方法。
结构体与共用体小结结构体和共用体是C语言中非常重要的数据类型。
它们在存储和组织数据方面提供了更灵活的选择。
本文将从定义、声明、初始化、使用和比较等方面对结构体和共用体进行详细讨论。
一、结构体(Struct)结构体是一种能够存储不同类型数据的自定义数据类型。
它允许将不同类型的数据组合在一起,形成一个逻辑上的实体。
1.定义和声明结构体的定义使用关键字`struct`,可以像定义其他变量一样定义结构体。
例如:```cstruct Studentint id;char name[20];int age;};```在定义结构体后,可以使用该结构体类型声明变量。
例如:```cstruct Student stu1;```也可以一步完成结构体类型定义和变量声明。
例如:```cstruct Studentint id;char name[20];int age;} stu1;```2.初始化结构体变量可以使用初始化列表初始化。
例如:```cstruct Student stu1 = {1001, "John", 20};```3.使用结构体变量的成员可以通过`.`运算符访问。
例如:```cstu1.id = 1001;strcpy(, "John");stu1.age = 20;```4.比较结构体不能直接比较,但可以通过定义比较函数来比较。
例如:```creturn (stu1.id == stu2.id && strcmp(, ) == 0 && stu1.age == stu2.age);```二、共用体(Union)共用体是一种特殊的数据类型,它允许不同类型的成员共享同一块内存空间。
共用体的成员在内存中是相互重叠的,只有一个成员可以被赋值和使用。
1.定义和声明共用体的定义使用关键字`union`,可以像定义其他变量一样定义共用体。
例如:```cunion Dataint i;float f;char str[20];};```在定义共用体后,可以使用该共用体类型声明变量。
第十一章结构体和共用体11.1 本章基本知识结构11.2 知识难点解析1.结构体与共用体变量在计算机中占用多少内存?[解答] 结构体变量所占的内存长度等于所有各成员的长度之和,每个成员分别占有自己的内存单元;共用体变量所占的内存长度等于最长的成员的长度。
2.结构体和共用体的有几种不同的引用方法?[解答] 结构体和共用体一样,有两种引用办法,一种是采用成员(分量)运算符“.”;还有一种是采用指针的办法。
下面以结构体为例说明这两种不同的引用的方法。
struct stu{int num;char name[10];int age;} zhangsan, *lisi;要访问学生zhangsan年龄的办法有两种:zhangsan.age 或者(&zhangsan)—>age;要访问学生lisi年龄的办法也有两种:(*lisi).age 或者lisi—>age。
11.3 习题1.选择题(1).以下程序运行的输出结果是( )。
main(){union {char i[2];int m;}r;r.i[0]=2;r.i[1]=0;printf("%d\n",r.m);}A.2B.1C.0D.不确定[分析、解答] 答案为A。
本题涉及共用体的概念。
字符数组i[2]与整型变量m使用同一内存单元。
M占用2个字节,高字节对应i[1],低字节对应i[0],所以答案为A。
(2).有以下程序输出结果是( )。
#include<stdio.h>struct stu{int num;char name[10];int age;};void fun(struct stu *p){printf("%s\n",(*p).name);}main(){struct stu students[3]={{9801,"zhang",20},{9802,"Wang",19},{9803,"zhao",18}};fun(students+2);}A.ZhangB.ZhaoC.WangD.18[分析、解答]答案为B。
在main函数中,定义结构体类型数组student[3],并赋初值。
即student[0]={9801,〞zhang〞,20},student[1]={9802, 〞wang〞,19},student[2]={9803, 〞zhao〞,18},调用子函数fun,实参“student+2”为student[2]的首地址,则p指向student[2]的首地址,(*p).name即“zhao”。
(3).有下列程序输出结果是( )。
#include <stdio.h>main(){union{int k;char i[2];}*a,b;a=&b;a->i[0]=0x39;a->i[1]=0x38;printf("%x\n",a->k);}A.3839B.3938C.380039D.390038[分析、解答]答案为A。
题中a是指向共用体类型变量b的指针变量,整型变量k与字符数组i[2]共用。
一个存储单元,k的高位字节对应i[1],k的低位字节对应i[0].“0x39”表示十六进制数的39。
“%x”表示十六进制的格式输出。
(4).设有如下定义:struct num{ int a;float b;} data,*p;若有p=&data;则对data中的a 域的正确引用是( )。
A.(*p).data.aB.(*p).aC.p->data.aD.p.data.a[分析、解答]答案为B。
p指向结构体类型变量data的首地址,*p即代表data,因此答案为B。
(5).若有下面的说明和定义,则sizeof(struct aaa)的值是( )。
struct aaa{ int r1;double r2;float r3;union uuu{ char u1[5];long u2[2];}ua;}mya;A.30B.29C.24D.22[分析、解答] 答案为D。
这是结构体套用共用体的形式,共用体的长度为8。
sizeof 为长度运算符。
sizeof(struct aaa)等价于sizeof(mya)=2+8+4+8=22。
(6).设有以下定义typedef union{ long m;int k[5];char ch;} DATE;struct date{ int cat;DATE cow;double dog;} too;DATE max;则语句printf(〞%d〞,sizeof(struct date)+sizeof(max)))的执行结果是( )。
A.25B.30C.18D.8[分析、解答]答案为B。
本题用typedef声明新的类型名“DATE”来代替已有的类型名union。
sizeof是长度运算符。
max,cow都是共用体类型,长度为“int k[5]”的长度,即10。
所以:sizeof (struct date)+sizeof(max)=(2+10+8)+10=30。
(7).字符ˊ0ˊ的ASCII码的十进制数为48,且数组的第0个元素在低位,则以下程序的输出结果是( )。
#include <stdio.h>main(){ union{ int i[2];long m;char c[4];} r,*s=&r;s->i[0]=0x39;s->i[1]=0x38;printf(〞%c\n〞,s->c[0]);}A.39B.9C.38D.8[分析、解答]:答案为B。
“0x39”代表十六进制的39,即十进制的57,c[0] 对应i[0]的低字节,由于十进制的57在内存中不超过8个二进制位(大于255不可),所以对应c[0]的就是57。
而字符0的ASCII码的十进制数为48,57就对应字符‘9’。
因此答案为B。
(8).若已建立下面的链表结构,指针p,s分别指向图中所示的结点,则不能将所指的结点插入到链表末尾的语句组是( )。
data nextA. s->next=null;p=p->next;p->next=s;B. p=p->next;s->next=p->next;p->next=s;C. p=p->next;s->next=p;p->next=s;D. p=(*p).next;(*s).next=(*p).next;(*p).next=s;[分析、解答]:答案为C。
s->next=p;p->next=s使得p,s所指的节点构成了环路而不是链表。
(9).根据下面的定义,能打出字母M的语句是( )。
struct student{ char name[9];int age;}struct student class[10]={ 〞John〞,17, 〞Paul〞,19, 〞Mary〞,18,〞Adam〞,16};A.printf(〞%c\n〞,class[3].name);B.printf(〞%c\n〞,class[3].name[1]);C.printf(〞%c\n〞,class[2].name[1]);D.printf(〞%c\n〞,class[2].name[0];[分析、解答]:答案为 D。
本题的要点是结构体成员的表示。
class[10]是结构体类型的数组,每个元素的长度是11,前9 个字符型的放名字,后两个整型的放年龄。
A是指“Adam”。
B是指d。
C 是指a。
D指M。
(10). 下列程序的执行结果为( )。
struct str{ char *s;int i;struct str *sip;}main(){ static struct str a[]={{"abcd",1,a+1},{"efgh",2,a+2},{"ijkl",3,a}};struct str *p=a;int i=0;printf("%s%s%s",a[0].s,p->s,a[2].sip->s);printf("%d%d",i+2,--a[i].i);printf("%c\n",++a[i].s[3]);}A.abcd abcd abcd 2 0 eB.abcd efgh ijkl 2 0 eC.abcd abcd ijkl 2 0 eD.abcd abcd abcd 2 1 e[分析、解答]:答案为 A。
(11). 下面程序的输出结果为( )。
struct st{ int x;int *y;} *p;int data[4]={10,20,30,40};struct st aa[4]={50,&data[0],60,&data[1],70,&data[2],80,&data[3]};main(){ p=aa;printf("%d\n",++p->x);printf("%d\n",(++p)->x);printf("%d\n",++(*p->y));}A.10B.50C. 51D.6020 60 60 7020 21 21 31[分析、解答]答案为C。
本题的说明中定义了一个名为st的结构体。
它由两个成员组成:一个是整型变量x;一个是指针变量。
在定义的同时说明了一个指向这一结构类型的指针变量p.数组每个元素是一个含有两个成员的struct st型的结构,并赋有初值。
在main函数中执行p=aa;语句后,p指向了数值的首地址,它们之间的关系如图所示:这里需要注意运算符的优先级,对于题目中涉及的运算符()、—>、++、*,其中括号最优先,其次是指向结构体成员运算符—>,下来是自增运算符++和指针运算符*,它们属于同级运算,其结合方向是“自右至左”。
参照上图可知,第一条printf语句的输出项++p→x是先找出p→(其值为50),再将其值自增1,取增值后的值,故输出51。
第二条printf语句的输出项为(++p)→x,它表示先将指针p自增1,指向aa数组的第二个元素aa[1],然后取其第一个成员aa[1].x的值。
故输出为60。
第三次的输出项为++(*p→y)。
此时p已指向aa[1],因此输出项等价于++(data[1]),先取出data[1]的值(20),再将其增1,故输出21。
由此可见,答案C正确。