结构体和共用体.ppt
《结构体和共用体.ppt》由会员分享,可在线阅读,更多相关《结构体和共用体.ppt(93页珍藏版)》请在三一办公上搜索。
1、第8章 结构体和共用体,前面的章节中已经介绍了各种基本数据类型、数组和指针。但只有这些数据类型还难以处理一些比较复杂的数据结构。本章将以前面介绍的数据类型为基础,进一步介绍结构体类型、共用体类型和枚举类型。,8.1 结构体 8.2 动态内存分配与链表 8.3 共用体类型 8.4 枚举类型 8.5 用户自定义类型 8.6 程序举例,第8章 结构体和共用体,第8章,8.1 结 构 体,8.1 结构体,8.1.1 结构类型定义 在实际问题中,一组数据往往具有不同的数据类型。例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。但这些显然不能用一
2、个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,语言中给出了另一种构造数据类型“结构体”。“结构体”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。结构体既然是一种“构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调用函数之前要先定义函数一样。,8.1 结构体,定义一个结构体类型的一般形式为:struct 结构体名 结构成员的说明;成员表由若干个成员组成,每个成员都是该结构体的一个组成部分。对每个成员也必须作类型说明,其形式为:类型说明符 成员名;成员名的命名
3、应符合标识符的书写规定。例如:struct stu int num;char name20;char sex;float score;,8.1 结构体,在这个结构体定义中,结构体名为stu,该结构体由4个成员组成。第一个成员为num,整型变量;第二个成员为name,字符数组变量;第三个成员为sex,字符变量;第四个成员为score,实型变量。应注意在括号“”后的分号是不可少的。结构体定义之后,即可进行变量说明。凡说明为结构体stu的变量都由上述4个成员组成。由此可见,结构是一种复杂的数据类型,是数目固定,类型不同的若干有序变量的集合。,8.1 结构体,8.1.2 结构体类型变量的说明 说明结构
4、体变量有以下三种方法。以上面定义的stu为例来加以说明。(1)先定义结构体类型,再说明结构体变量 例如:struct stu int num;char name20;char sex;float score;struct stu boy1,boy2;说明了两个变量boy1和boy2为stu结构类型。也可以用宏定义使用一个符号常量来表示一个结构类型,例如:#define STU struct stu STU int num;char name20;char sex;float score;STU boy1,boy2;,8.1 结构体,(2)在定义结构体类型的同时说明结构体变量 例如:struct
5、 stu int num;char name20;char sex;float score;boy1,boy2;(3)直接说明结构体变量 例如:struct int num;char name20;char sex;float score;boy1,boy2;,8.1 结构体,第三种方法与第二种方法的区别在于第三种方法中省去了结构体名,而直接给出结构体变量。三种方法中说明的boy1,boy2变量都具有相同的结构。说明了boy1,boy2变量为stu类型后,即可向这两个变量中的各个成员赋值。在上述stu结构体定义中,所有的成员都是基本数据类型或数组类型。成员也可以又是一个结构体类型,即构成了嵌套
6、的结构体。,8.1 结构体,例如:struct date int month;int day;int year;struct int num;char name20;char sex;struct date birthday;float score;boy1,boy2;,首先定义一个结构体date,由month(月)、day(日)、year(年)三个成员组成。在定义并说明变量 boy1 和 boy2 时,其中的成员birthday被说明为data结构体类型。成员名可与程序中其它变量同名,互不干扰。结构体变量成员的表示方法,在程序中使用结构体变量时,往往不把它作为一个整体来使用。,说明:结构体在
7、内存中存储容量是各成员容量之和,这是与后面联合体的重要区别。,8.1 结构体,8.1.3 结构体变量的引用 一般情况下,不能对一个结构体变量作为整体引用,只能引用其中的成员。结构体变量中成员引用的一般形式为:结构体变量名.成员名其中,“.”是域成员运算符,是C语言中优先级最高的运算符之一。例如:boy1.num 即第一个人的学号,boy2.sex 即第二个人的性别。如果成员本身又是一个结构体,则必须逐级找到最低级的成员才能使用。例如:boy1.birthday.month 即第一个人出生的月份。成员可以在程序中单独使用,与普通变量完全相同。,8.1 结构体,8.1.4 结构体变量的赋值对于结构
8、体变量,只有以下两种情况可以对结构体变量赋值。(1)结构体变量整体赋值 例如:boy2=boy1;(2)取结构体变量地址 例如:这些语句都是不允许的,只能对结构体成员进行输入/输出。,8.1 结构体,例8.1 给结构体变量赋值并输出其值。#include void main()struct stu/*定义结构体stu*/int num;char*name;char sex;float score;boy1,boy2;/*定义stu类型的变量boy1、boy2*/boy1.num=102;boy1.name=Zhang ping;printf(input sex and score:n);sca
9、nf(%c%f,8.1 结构体,程序运行结果:input sex and score:M 96number=102name=Zhang pingsex=Mscore=96.00,本程序中用赋值语句给num和name两个成员赋值,name是一个字符串指针变量。用scanf()函数动态地输入sex和score成员值,然后把boy1的所有成员的值整体赋予boy2。最后分别输出boy2 的各个成员值。,8.1 结构体,8.1.5 结构体变量的初始化 如果结构体变量为全局变量或者静态变量,则可以对它做初始化赋值。对局部或自动结构体变量不能做初始化赋值。,8.1 结构体,例8.2 外部结构体变量初始化。#
10、include struct stu/*定义结构体*/int num;char*name;char sex;float score;boy2,boy1=102,Zhang ping,M,78.5;/*对变量boy1的成员初始化*/void main()boy2=boy1;/*把boy1整体赋给boy2*/printf(number=%dnname=%sn,boy2.num,boy2.name);printf(sex=%cnscore=%6.2fn,boy2.sex,boy2.score);,8.1 结构体,程序运行结果:number=102name=Zhang pingsex=Mscore=7
11、8.50,本程序中,boy2,boy1均被定义为外部结构体变量,并对boy1作了初始化赋值。在main()函数中,把boy1的值整体赋予boy2,然后用两个printf()语句输出boy2各成员的值。,8.1 结构体,例8.3 静态结构体变量初始化。#include void main()static struct stu/*定义静态结构体*/int num;char*name;char sex;float score;boy2,boy1=102,Zhang ping,M,78.5;/*对变量boy1的成员初始化*/boy2=boy1;printf(number=%dnname=%sn,boy
12、2.num,boy2.name);printf(sex=%cnscore=%6.2fn,boy2.sex,boy2.score);本程序是把boy1,boy2都定义为静态局部的结构体变量,同样可以做初始化赋值。,8.1 结构体,8.1.6 结构体数组 一个结构体变量可以处理一个对象,如果有多个对象,则需要多个结构体变量,数组的元素也可以是结构体类型的,因此可以构成结构体数组。结构体数组的每一个元素都是具有相同结构体类型的下标结构体变量。在实际应用中,经常用结构体数组来表示具有相同数据结构的一个群体。如一个班的学生档案,一个车间职工的工资表等。结构体数组的定义方法和结构体变量相似,也有三种方式:
13、(1)先定义结构体类型,再定义结构体数组。例如:struct stu int num;char*name;char sex;float score;;struct stu boy5;定义了一个结构体数组boy,共有5个元素,boy0boy4。每个数组元素都具有struct stu的结构体形式。,8.1 结构体,(2)在定义结构体类型的同时定义结构体数组。例如:struct stu int num;char*name;char sex;float score;boy5;(3)直接定义结构体数组。例如:struct int num;char*name;char sex;float score;bo
14、y5;,8.1 结构体,对外部结构体数组或静态结构体数组可以做初始化赋值。例如:struct stu int num;char*name;char sex;float score;boy5=101,Li ping,M,45,102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58;当对全部元素做初始化赋值时,也可不给出数组长度。,8.1 结构体,例8.4 计算学生的平均成绩和不及格的人数。#include struct stu/*定义结构体*/int num;char*name;char se
15、x;float score;boy5=101,Li ping,M,45,102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58;/*对结构体数组元素初始化*/void main()int i,c=0;float ave,s=0;for(i=0;i5;i+)s+=boyi.score;if(boyi.score60)c+=1;printf(s=%6.2fn,s);ave=s/5;/*计算平均成绩*/printf(average=%6.2fncount=%dn,ave,c);,8.1 结构体,程
16、序运行结果:s=345.00average=69.00count=2,本例程序中定义了一个外部结构体数组boy,共5个元素,并作了初始化赋值。在main函数中用for语句逐个累加各元素的score 成员值存于s之中,如score的值小于60(不及格),即计数器C加1,循环完毕后计算平均成绩,并输出全班总分、平均分及不及格人数。,8.1 结构体,例8.5 建立同学通讯录。#include#define NUM 2struct mem/*定义结构体*/char name20;char phone10;void main()struct mem manNUM;int i;for(i=0;iNUM;i
17、+)/*输入通讯录*/printf(input name:);gets(mani.name);printf(input phone:);gets(mani.phone);printf(NamettPhonen);for(i=0;iNUM;i+)/*输出通讯录*/printf(%st%sn,mani.name,mani.phone);,8.1 结构体,程序运行结果:input name:Zhang juninput phone:88888888input name:Wang fanginput phone:99999999Name PhoneZhang jun 88888888Wang fang
18、 99999999,本程序中定义了一个结构体类型mem,它有两个成员name和phone,用来表示姓名和电话号码。在主函数中定义man为具有mem 类型的结构体数组。在for语句中,用gets()函数分别输入各个元素中两个成员的值。然后又在for语句中用printf()语句输出各元素中两个成员值。,8.1 结构体,8.1.7 指向结构体变量的指针变量 结构体指针变量是一个指针变量,用来指向改变量所分配的存储区域的首地址。结构体指针变量还可以用来指向结构体数组中的元素。结构体指针与以前介绍的各种指针在特性和使用方法上完全相同。结构体指针变量的运算也按照C语言的地址计算规则进行的。例如,结构体指针
19、变量加1将指向内存中下一个结构体变量,结构体指针变量自身地址值的增加量取决于它所指向的结构体变量的数据长度(sizeof()函数获取)。总之,结构体指针变量是指向一个结构体变量的指针变量。,8.1 结构体,1.结构体指针变量的定义 定义结构体指针变量的一般形式为:struct 结构体类型名*结构指针变量名;例如:struct stu int num;char*name;char sex;float score;boy,*pstu;pstu=也可以定义结构体类型后再定义结构体指针变量。结构体名和结构体变量是两个不同的概念,不能混淆。结构体名只能表示一个结构体形式,编译系统并不对它分配内存空间。只
20、有当某变量被说明为这种类型的结构时,才对该变量分配存储空间。有了结构指针变量,就能更方便地访问结构变量的各个成员。,8.1 结构体,2.结构体指针变量的赋值 结构体指针变量必须先赋值后使用。赋值是把结构体变量的首地址赋给该指针变量,不能把结构名赋给该指针变量。例如,不能写成pstu=。,8.1 结构体,3.结构体指针变量的引用 定义好一个结构体指针变量之后,就可以对该指针变量进行各种操作。例如,给一个结构体变量指针赋一个地址值,输出一个结构体变量指针的成员值,访问结构体变量指针所指向的变量的成员等。引用结构体指针变量的一般形式为:(*结构指针变量).成员名;或 结构指针变量-成员名;例如:(*
21、pstu).num;或 pstu-num;应该注意(*pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。如去掉括号写作*pstu.num,则等效于*(pstu.num),这样,意义就完全不对了。,8.1 结构体,例8.6 分析下面程序的运行结果。#include struct stu/*定义结构体*/int num;char*name;char sex;float score;boy1=102,Zhang ping,M,78.5,*pstu;void main()pstu=,8.1 结构体,本程序序定义了一个结构体类型stu,定义了stu类型结构变量boy1 并作了初始化赋值,还
22、定义了一个指向stu类型结构体的指针变量pstu。在main()函数中,pstu被赋予boy1的地址,因此pstu指向boy1。然后在printf()语句内用三种形式输出boy1的各个成员值。,程序运行结果:number=102name=Zhang pingsex=Mscore=78.50,8.2 动态内存分配与链表,我们存储数量比较多的同类型或同结构的数据时,一般首先考虑数组。然而在实际应用中,当处理一些难以确定其数量的数据时,如果用数组来处理,必须事先分配一个足够大的连续空间,以保证数组元素数量充分够用,但这样处理时对存储空间的一种浪费。C 语言使用动态内存分配来解决这样的问题,其中常用的
23、就是链表。链表是一种常见的数据结构,它动态地进行存储分配,并且可以方便而又简单地进行数据插入,删除等操作。,8.2 动态内存分配与链表,8.2.1 链表的概念 链表是指若干个数据按一定的原则连接起来。这个原则为:前一个数据指向下一个数据,只有通过前一个数据项才能找到下一个数据项。链表有一个“头指针”(head),它指向链表的第一个元素(数据项)。链表的一个元素称为一个“结点”(node)。结点中包含两部分内容,第一部分是结点数据本身,如图8-1中的、所示。结点的第二部分是一个指针,它指向下一个结点。最后一个结点称为“表尾”,表尾结点的指针不指向任何地址,因此为空(NULL)。,图8-1 链表结
24、构图,8.2 动态内存分配与链表,如果每个结点采用一个指针,将前一个结点的指针指向下一个结点,这称为单链表。如果每个结点有两个指向其他结点的指针,则称为双链表。本节主要讨论单链表的运算。由以上简单链表可以看到,链表中的每个结点至少包含两个域,一个域用来存放数据,其类型根据需存放的数据类型定义。另一个域用来存放下一个结点的地址,因此必然是一个指针类型,此指针的类型应该是所指向的表结点的结构体类型。在C语言中,可以用结构体类型来实现链表,例如:struct student int long;float score;struct student*next;/*指向下一结点*/;其中next是结构体指
25、针变量,用来存放下一个结点的地址,即next是指向下一个结点。,8.2 动态内存分配与链表,8.2.2 动态存储分配 C语言允许在函数执行部分的任何地方使用动态存储分配函数开辟或收回存储单元,这样的存储分配叫动态存储分配。动态分配使用自由、节约内存。链表是动态分配存储空间的,也就是说在需要的时候才开辟一个结点的存储空间。在C语言中提供了以下有关的函数来实现动态存储分配和释放,这些函数包含在“stdio.h”或“malloc.h”中。,8.2 动态内存分配与链表,1.malloc()函数(分配内存空间函数)调用形式为:void*malloc(size);其作用是在内存中动态获取一个大小为size
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 结构 共用

链接地址:https://www.31ppt.com/p-5313833.html