第8章结构体共用体和枚举类型

上传人:桔**** 文档编号:568496724 上传时间:2024-07-24 格式:PPT 页数:89 大小:339.50KB
返回 下载 相关 举报
第8章结构体共用体和枚举类型_第1页
第1页 / 共89页
第8章结构体共用体和枚举类型_第2页
第2页 / 共89页
第8章结构体共用体和枚举类型_第3页
第3页 / 共89页
第8章结构体共用体和枚举类型_第4页
第4页 / 共89页
第8章结构体共用体和枚举类型_第5页
第5页 / 共89页
点击查看更多>>
资源描述

《第8章结构体共用体和枚举类型》由会员分享,可在线阅读,更多相关《第8章结构体共用体和枚举类型(89页珍藏版)》请在金锄头文库上搜索。

1、第第8章章 结构体、共用体和枚举类型结构体、共用体和枚举类型n教学目的教学目的:通过本章的学习,要求了解结构型、链表、通过本章的学习,要求了解结构型、链表、共用型和枚举型数据的特点,熟练掌握结构型共用型和枚举型数据的特点,熟练掌握结构型的定义方法,结构型变量、数组、指针变量的的定义方法,结构型变量、数组、指针变量的定义、初始化和成员的引用方法;掌握简单链定义、初始化和成员的引用方法;掌握简单链表的基本操作原理和应用;掌握共用型和枚举表的基本操作原理和应用;掌握共用型和枚举型的定义方法及对应变量的定义与引用;掌握型的定义方法及对应变量的定义与引用;掌握用户自定义类型的定义和使用。学习本章内容用户

2、自定义类型的定义和使用。学习本章内容可以为今后学习数据结构中的链表创建和使用可以为今后学习数据结构中的链表创建和使用打下基础。打下基础。熊疏兢蓉牛漳亿鹤往诛讣鲁浊痒婆辛筏弥契霸宗矣扔签简屿肆男短削羔隘第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型第第8章章 结构体、共用体和枚举类型结构体、共用体和枚举类型 n教学内容教学内容 结构型的引入,很好的处理生活总的各种表格或表格中的记录结构型的引入,很好的处理生活总的各种表格或表格中的记录结构型的定义,结构型变量的定义、赋值、引用及引用链表等方法结构型的定义,结构型变量的定义、赋值、引用及引用链表等方法共用型的定义,共用型变量的定义、赋值、

3、引用共用型的定义,共用型变量的定义、赋值、引用枚举型的定义,共用型变量的定义、赋值、引用枚举型的定义,共用型变量的定义、赋值、引用岂狸愈贸肯炊渴尼隧淄芬参哟可迟吓曳扛拱质蚜担名套蛇社纪陇绪余痞抽第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型第第8章章 结构体、共用体和枚举类型结构体、共用体和枚举类型n重点和重点和难难点点重点:重点: (1)结构型、共用型、枚举型数据的特点和定义结构型、共用型、枚举型数据的特点和定义 (2)结构型变量、数组、指针变量的定义、初始化和成员结构型变量、数组、指针变量的定义、初始化和成员引用方法引用方法 (3)共用型和枚举型变量的定义和引用方法共用型和枚举型

4、变量的定义和引用方法难点难点: (1)嵌套的结构型数据的处理嵌套的结构型数据的处理 (2)用结构体解决链表问题(建立、插入、删除、输出和用结构体解决链表问题(建立、插入、删除、输出和查询)。查询)。 体井哺滦以曙浚左捻仙证财瘟两杭娱郝艰钦呐腑娱熊赎整峰哼羞墅句携拐第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.1 结构体类型结构体类型结构型是用户自己定义的数据类型结构型是用户自己定义的数据类型蛋检渣蠕遇函长幼汞车菱录旧邯冶车件瓶淬擦烧曝声限墓甲中墒挞廖绦忆第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.1.1 结构体型的实例结构体型的实例 前面我们学习过了基本数据类型,

5、例如:前面我们学习过了基本数据类型,例如:short、long、int 、float、double、char等,这些基本数据类型都是系统等,这些基本数据类型都是系统已经定义好的,用户可以直接使用它们。但现实世界是复已经定义好的,用户可以直接使用它们。但现实世界是复杂的,在我们的日常生活中有很多的表格,各表格之间又杂的,在我们的日常生活中有很多的表格,各表格之间又有关联。因此用户需要自己定义数据类型,用户自己定义有关联。因此用户需要自己定义数据类型,用户自己定义的数据类型一旦定义好之后,就可以像使用系统类型一样的数据类型一旦定义好之后,就可以像使用系统类型一样使用它。例如:对一个新生进行入学登记

6、时,就需要填一使用它。例如:对一个新生进行入学登记时,就需要填一张表格,填写的内容包括姓名、性别、学号、年龄、家庭张表格,填写的内容包括姓名、性别、学号、年龄、家庭住址、联系电话、总分等多个数据项,其中姓名是字符串住址、联系电话、总分等多个数据项,其中姓名是字符串型(可以用字符数组来表示),性别是字符型(用型(可以用字符数组来表示),性别是字符型(用m表示表示男性、用男性、用f表示女性),年龄是整型,总分是实型。表示女性),年龄是整型,总分是实型。 术扦潭靳磺诡到钱诉烤疮呢胚耻缝钎岳傣壁斥煞榴笼穆慷杯削孪傀盲碘拖第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型 如图如图8-1所示,所示

7、, 这些数据项之间关系紧密,每一个这些数据项之间关系紧密,每一个学生通过姓名、性别、学号、年龄、家庭地址、联系学生通过姓名、性别、学号、年龄、家庭地址、联系电话、总分等属性构成一个整体反映一个学生的基本电话、总分等属性构成一个整体反映一个学生的基本情况。如果将姓名、性别、学号、年龄、家庭地址、情况。如果将姓名、性别、学号、年龄、家庭地址、联系电话、总分分别定义为互相独立的简单变量,难联系电话、总分分别定义为互相独立的简单变量,难以反映它们之间的内在联系。为了方便处理此类数据,以反映它们之间的内在联系。为了方便处理此类数据,常常把这些关系密切但类型不同的数据项组织在一起,常常把这些关系密切但类型

8、不同的数据项组织在一起,即即“封装封装”起来,并为其取一个名字,在语言中就起来,并为其取一个名字,在语言中就称其为结构体(也人称为构造体),结构体是用户自称其为结构体(也人称为构造体),结构体是用户自定义数据类型的一种。定义数据类型的一种。斜枕粪揣青梭梯墩垫蝴鲜糊盂磨丹气鸣惫层躲碟弄棺捂养耘陵棠扎罩顶赵第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.1.2 结构体类型的定义结构体类型定义的一般形式结构体类型定义的一般形式struct 结构型名结构型名数据类型标识符成员;数据类型标识符成员; 数据类型标识符成员;数据类型标识符成员; 数据类型标识符成员数据类型标识符成员n; ; 请读

9、者注意结构体定义语句的右花括号后面用分号(;)请读者注意结构体定义语句的右花括号后面用分号(;)做语句结束标记。做语句结束标记。磋筷弱纳怯杨颖徒验赋当勉皋精腺屁剥姿服爹镣婿蒸缅港湍宴砾秽汽牌升第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.1.2 结构体类型的定义结构体型定义实例结构体型定义实例n例如:为了存放一个人的姓名、性别、年龄、工资,例如:为了存放一个人的姓名、性别、年龄、工资,可以定义如下的结构型:可以定义如下的结构型: struct person char name10; char sex; int age; float wage; ; /*这个名为这个名为person

10、的结构型共含有的结构型共含有4个成员个成员*/卒絮泛答珊芜局卫盾园冶垢钎敢涟郡扬圆沧砒捏驼卒倾远霄梦挫闹辑沧牢第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.1.2 结构体类型的定义 结构型嵌套定义结构型嵌套定义结构型嵌套定义结构型嵌套定义【例8.1】一开始所讲的例题中的birthday类型和person类型。 struct birthday /*定义含有定义含有3个整型成员的结构型个整型成员的结构型 birthday*/ int year; int month; int day;struct person /*定义含有定义含有4个成员的结构型个成员的结构型 person*/cha

11、r name20; char sex; struct birthday bir; /*该成员的数据类型是结构型该成员的数据类型是结构型*/ float wage;渝岩首贺滁绳玲侯孪却课怕太氏浩银赂斯榨部殖醒熏撅枷手值磁吠杏蚤结第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.2.1结构型变量的定义和初始化结构型变量的定义和初始化n先定义结构型,后定义变量先定义结构型,后定义变量n定义结构型的同时定义变量定义结构型的同时定义变量 n定义无名称的结构型的同时定义变量定义无名称的结构型的同时定义变量 8.2 结构体变量的定义和引用结构体变量的定义和引用还村壶组剑翁誊犊他蹿隶幼笋挪晾蓑双荧唯

12、彪抽蜕瞒戴已委惩聘狙财宽傀第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型 例如:为学生信息定义例如:为学生信息定义2个变量个变量x和和y , 程序段如下:程序段如下:struct studentlong number; char name20; char sex; float score3;struct student x,y;在定义变量的同时,可以变量赋初值,例如上例中的定义语在定义变量的同时,可以变量赋初值,例如上例中的定义语句可以改写如下:句可以改写如下:struct student x=100001L,”Tom”,m,86,94,89, y=100002L,”Lucy”,f,

13、78,88,45;1. 先定义结构型,后定义变量先定义结构型,后定义变量 绚要弥掠虫求凋噬寿琴蚁弘精泉蛔拳甜乌赤耳祥玫甄硷尽熏愿依桅兔章阂第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型淬懦啊匀粱共胜馁晤疯图址祷菜寡莱噎楷前丫欠碘主童殖烯侵疹渭变账辐第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2. 定义结构型的同时定义变量定义结构型的同时定义变量例如:为学生信息定义例如:为学生信息定义2个变量个变量x和和y , 并给他们赋初并给他们赋初值,程序段如下:值,程序段如下:struct studentlong number; char name10; char sex; floa

14、t score3;x=100001L,”Tom”,m,86,94,89, y=100002L,”Lucy”,f,78,88,45,;这种方法是将类型定义和变量定义同时进行。以后这种方法是将类型定义和变量定义同时进行。以后仍然可以使用这种结构型来定义其它的变量。仍然可以使用这种结构型来定义其它的变量。 弧标锤嘉臆处峨坯墙钮辽姚展臀葫锁岿螺蛋侧戳虎菇邵报茫飘筐迭疡酿铬第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3. 定义无名称的结构型的同时定义变量定义无名称的结构型的同时定义变量例如:为学生信息定义例如:为学生信息定义2个变量个变量x和和y ,并给它们赋初值,程并给它们赋初值,程序段如

15、下:序段如下:structlong number; char name10; char sex; float score3;x=100001L,”Tom”,m,86,94,89, y=100002L,”Lucy”,f,78,88,45,;这种方法是将类型定义和变量定义同时进行,但结构型的这种方法是将类型定义和变量定义同时进行,但结构型的名称省略,以后将无法使用这种结构型来定义其它变量,名称省略,以后将无法使用这种结构型来定义其它变量,建议尽量少用。建议尽量少用。 词芳搐烬淋楔哎役虚突蜗杆灼绚侦笆柠次脾涂署思灵煎帆票三乌瑰坚方避第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.2.2

16、结构型变量成员的引用结构型变量成员的引用1.结构型变量成员的结构型变量成员的引用方法引用方法2.结构型变量成员地址的结构型变量成员地址的引用方法引用方法3.结构型变量地址的结构型变量地址的引用方法引用方法紧县挺曝钥泥凰寸乌仅朴洗泡透陛炕跨醋笛冯直圭拄嘱澜呻梦岭粗暴伎苹第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型1. 1. 结构型变量成员的引用方法结构型变量成员的引用方法结构型变量成员的引用方法结构型变量成员的引用方法结构型变量成员的引用格式如下:结构型变量成员的引用格式如下:n结构型变量名结构型变量名. 成员名成员名 其中的其中的“.”称为成员运算符,其运算级别是最称为成员运算符,

17、其运算级别是最高的,和圆括号运算符高的,和圆括号运算符“()()”、下标运算符、下标运算符“”是同级别的,运算顺序是自左向右。是同级别的,运算顺序是自左向右。如果某个结构型变量的成员数据类型又是一个结构型,如果某个结构型变量的成员数据类型又是一个结构型,则其成员的引用方法如下:则其成员的引用方法如下:n外层结构型变量外层结构型变量. 外层成员名外层成员名. 内层成员名内层成员名詹识紧先柜诈雕熊痊敛逻痉炮陌酱豆蹬拨汕话花箱方袒冻古溃禄焉算聚长第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型结构型变量成员的引用实例结构型变量成员的引用实例结构型变量成员的引用实例结构型变量成员的引用实例【例

18、8.2】求Tom的三门课程的成绩总分,并在显示器显示出来(使用结构型变量成员的引用)。 #include”string.h” struct student long number; char name10; char sex; float score3; ; main() struct student stu1; /*定义student类型的变量stu1*/ stu1.number=100001L; /*给结构型变量stu1的成员number赋值*/ strcpy(stu1.name;”Tom”); /*给结构型变量stu1的成员name赋值*/ stu1.sex=f; /*给结构型变量stu

19、1的成员sex赋值*/ stu1.score0=89; /*给结构型变量stu1的成员score赋值*/ stu1.score1=91; stu1.score2=86; printf(“%s的总分是:%fn”,stu.name,stu1.score0+stu1.score1+stu1.score2); 谣家善柏绑缎逗憾器磨途燃纷窘椽慨渤续却脑凡炽可饰邦丁宅氛粒溅变悯第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2. 2. 结构型变量成员地址的引用方法结构型变量成员地址的引用方法结构型变量成员地址的引用方法结构型变量成员地址的引用方法结构型的变量成员地址引用格式如下:结构型的变量成员地

20、址引用格式如下:n &结构型的变量名结构型的变量名.成员名成员名存放结构型变量成员地址的指针变量类型必须和该成存放结构型变量成员地址的指针变量类型必须和该成员的类型相同。员的类型相同。擅匹漳彪比撒削按超杨诡杏废吼踏绰效狮富享查党掘薪酞迁碌快牛宜创尝第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型【例8.4】结构型变量成员地址引用。 #include “string.h” /*程序中使用了字符串处理函数程序中使用了字符串处理函数*/ sturct student2 /*定义定义student2结构型结构型*/ long number; char name10; main() struct

21、 student2 x; /*定义定义student2类型的变量类型的变量x*/ long *p_number; /*定义能指向结构型定义能指向结构型student成员成员number的指针变量的指针变量*/ char *p_name; /*定义能指向结构型定义能指向结构型student成员成员namer的指针变量的指针变量*/ p_number=&x.number; /*让指针变量指向结构型变量让指针变量指向结构型变量x的成员的成员*/ *p_ number=100001L; /*用指针变量给结构型变量用指针变量给结构型变量x的所有成员赋值的所有成员赋值*/ strucpy(p_ name,

22、”zhongxin”); printf(“number=%1d name=%sn”,*p_number,*p_ name); /*用指针变量输出结构型变量用指针变量输出结构型变量x所有成员的值所有成员的值*/ 从这个例子可以看出,使用指向结构型变量成员的指针变量来引用成员的方法比较繁从这个例子可以看出,使用指向结构型变量成员的指针变量来引用成员的方法比较繁琐,可以直接使用结构型变量的指针成员来引用成员。具体使用方法请参看第琐,可以直接使用结构型变量的指针成员来引用成员。具体使用方法请参看第8章章8.4节。节。盲聋晾闪窥以辊予贼患漳辐昂米犹盘滩嘎邹编讽叁狠加抵诞脸肢研直靴馒第8章结构体共用体和枚

23、举类型第8章结构体共用体和枚举类型3. 3. 结构型变量地址的引用方法结构型变量地址的引用方法结构型变量地址的引用方法结构型变量地址的引用方法 结构型变量地址的引用格式如下:结构型变量地址的引用格式如下: &结构型变量名结构型变量名 例如:借用例例如:借用例8.4中的结构型中的结构型struct student2: struct student2 y,*sty=&y;存放结构型变量地址的指针变量必须是类型相同的结构存放结构型变量地址的指针变量必须是类型相同的结构型指针,关于如何使用结构型变量地址的例子请参见型指针,关于如何使用结构型变量地址的例子请参见8.4节中介绍的指向结构型数据的指针变量。

24、节中介绍的指向结构型数据的指针变量。酸骤乡按押阅榆备远赚株血贞勾妥线租毙靳们伐女胆莱渴袭生初羊瑶撵霉第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.3 结构型数组的定义和引用结构型数组的定义和引用 在实际应用中,我们经常要处理的是具有在实际应用中,我们经常要处理的是具有 相同数据结构的一个群体。比如一批书,所有相同数据结构的一个群体。比如一批书,所有员工的通信地址,一个班级的学生等。由相同员工的通信地址,一个班级的学生等。由相同结构类型变量组成的数组,称为结构型数组。例结构类型变量组成的数组,称为结构型数组。例如,全班有如,全班有40人,在总成绩单上每人占一行,每人,在总成绩单上每

25、人占一行,每行的内容包括学号、姓名、行的内容包括学号、姓名、3门功课的成绩、平门功课的成绩、平均分、名次,这样一个总成绩单就可以用结构型均分、名次,这样一个总成绩单就可以用结构型数组表示。数组表示。榔绚擞味奄超纬嗣整辆脚毙躬奈婉旬洁邱匣邑硝伙达据沿刽劝扦纠凶凹谬第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.3.1 结构型数组的定义和初始化结构型数组的定义和初始化1.先定义结构型,然后再定义结构型数组并赋初值先定义结构型,然后再定义结构型数组并赋初值 2.定义结构型的同时定义数组并赋初值定义结构型的同时定义数组并赋初值 3.定义无名称的结构型的同时定义数组并赋初值定义无名称的结构型

26、的同时定义数组并赋初值 晰惟软七瘩纳巢琅腕僧生挪秤锰潞菩澜帛埠雹敝乡砂直杖旬陕卷镭皑姜凤第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型 1.1.1.1.先定义结构型,再定义结构型数组并赋初值运算先定义结构型,再定义结构型数组并赋初值运算先定义结构型,再定义结构型数组并赋初值运算先定义结构型,再定义结构型数组并赋初值运算 struct student /*定义结构型定义结构型*/ long number; char name10; char sex; float score3; ; struct student s3= 200001L,”Tom”,m,78,86,92 , 200002

27、L,”Lucy”,f,85,69,82 , 200003L,”Jack”,m,84,88,96 ;鼻像捡麓匣敌捍垣累脱钒棠扮辞落蝶吠践你皖氦册蒙柠礁凰孽大似颜庭艇第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2. 定义结构型的同时定义数组并赋初值定义结构型的同时定义数组并赋初值 struct student /*定义结构型定义结构型*/long number;char name10;char sex;float score3;s3= 200001L,”Tom”,m,78,86,92 , 200002L,”Lucy”,f,85,69,82 , 200003L,”Jack”,m,84,8

28、8,96 ;梅慨且渣拓睁广竹郡谢陷堡十侍葱悠苹属撕闰彭坤氨虱狱任撞灭噶盟沂叶第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3. 3. 定义无名称的结构型的同时定义数组并赋初值定义无名称的结构型的同时定义数组并赋初值定义无名称的结构型的同时定义数组并赋初值定义无名称的结构型的同时定义数组并赋初值 struct /*定义结构型定义结构型*/long number;char name10;char sex;float score3;s3= 200001L,”Tom”,m,78,86,92 , 200002L,”Lucy”,f,85,69,82 , 200003L,”Jack”,m,84,8

29、8,96 ;擞晋波东六嘻哈拔糜骗忧滥许肆席皑毡轿砚愁行饱裂却健挚渔交贷斗款交第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.3.2 结构型数组元素成员的引用结构型数组元素成员的引用1.结构型数组元素的引用结构型数组元素的引用格式如下格式如下; 结构型数组名结构型数组名下标下标 . 成员名成员名2.结构型数组元素成员地址的引用结构型数组元素成员地址的引用格式如下格式如下: &结构型数组名结构型数组名下标下标.成员名成员名锗哎梢呻络侥韭栈肺瓣丰傅学掘棚笼堕磋恼旗景噎利澡彬宾性掣蚂缸蛾管第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型1. 1. 结构型数组元素的引用结构型数组元素

30、的引用结构型数组元素的引用结构型数组元素的引用:结构型数组名结构型数组名结构型数组名结构型数组名 下标下标下标下标 . . 成员名成员名成员名成员名n【例【例8.5】输入】输入3个学生的数据,每个学生的信息个学生的数据,每个学生的信息由学号、姓名和三门功课的成绩组成,然后计算每由学号、姓名和三门功课的成绩组成,然后计算每一个学生的总分,并输出总分最高的学生信息。一个学生的总分,并输出总分最高的学生信息。n分析:将分析:将3个学生定义为结构型类型数组,学号个学生定义为结构型类型数组,学号为长整型、成绩为实型数组,总分存在成绩数组中。为长整型、成绩为实型数组,总分存在成绩数组中。剂肛罕陷盏溃学序蒂

31、厌弦粉笋汇近勺远笑慰酿称渍郸燎桌林照央敦耘莹贱第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型#define N 3struct student /*定义结构型定义结构型*/ long number; char name10; float scoreN+1; /*score数组前三个元素用来存放成绩,第四个元素用来存数组前三个元素用来存放成绩,第四个元素用来存 放总放总分分*/ stuN; main() float max=0;int i,j,max_i=0;for(i=0;iN;i+)printf(“输入第输入第%d个学生的信息,依次输入学号,姓名,三个成绩,各数据个学生的信息,依次

32、输入学号,姓名,三个成绩,各数据之间用之间用,隔开隔开”,i);scanf(“%ld,%s,%f,%f,%f”, ,&stui.number,&stui.name,&stui.score0, &stui.score1, &stui.score2);stui.score3=stui.score0+ stui.score1+ stui.score2;if (max成员名成员名n 方式方式1比较好理解,其中比较好理解,其中“*指针变量指针变量”就代表了它就代表了它所指向的结构型变量,利用所指向的结构型变量,利用“成员运算符成员运算符”来引用,来引用,其作用相当于其作用相当于“结构型变量结构型变量.成

33、员名成员名”。需要注意的。需要注意的是是“*指针变量指针变量”必须用圆括号括住,因为必须用圆括号括住,因为“*”运算运算符的级别低于符的级别低于“.”运算符,如果不加括号,则优先运算符,如果不加括号,则优先处理处理“.”运算符,将出现运算符,将出现“指针变量指针变量.成员名成员名”,会,会造成语法错误。造成语法错误。n 方式方式2是一种新的引用方法,其中是一种新的引用方法,其中“-”称为称为“指向指向成员运算符成员运算符”,也简称,也简称“指向运算符指向运算符”。其运算级别。其运算级别和和“()()”、“”、“.”是同级的。指向运算符是同级的。指向运算符的左边必须是已指向某个结构型变量或数组元

34、素的指的左边必须是已指向某个结构型变量或数组元素的指针变量,其右边必须是对应结构型数据的成员名。针变量,其右边必须是对应结构型数据的成员名。彩通庭围槐碾绥脯蒲勇鸟刘梭类轩委课循务泻穆衡息看魂嫩欺旱帮框嫂沽第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.4.2 指向结构型数组的指针1.指针变量指向数组元素指针变量指向数组元素 如果一个结构型数组元素的地址已赋予相同结构型指针变量(即指针变量如果一个结构型数组元素的地址已赋予相同结构型指针变量(即指针变量指向结构型数组元素),可以使用下列两种方法来引用数组该元素的成指向结构型数组元素),可以使用下列两种方法来引用数组该元素的成员,其作用

35、完全相同。员,其作用完全相同。 方式方式1 (*指针变量)。成员名指针变量)。成员名 方式方式2 指针变量指针变量-成员名成员名 注意:这里的指针变量必须是指向某个数组元素的。例如,它指向的数组注意:这里的指针变量必须是指向某个数组元素的。例如,它指向的数组元素为元素为“数组名数组名k”,则上述两种引用方式均代表,则上述两种引用方式均代表“数组名数组名k。成员。成员名名”。2.指针变量指向数组首地址指针变量指向数组首地址 当一个结构型数组的首地址已经赋予相同结构型的指针变量(即指针变量当一个结构型数组的首地址已经赋予相同结构型的指针变量(即指针变量指向结构型数组),可以使用下列两种方式来引用下

36、标为指向结构型数组),可以使用下列两种方式来引用下标为i的数组元素成的数组元素成员,其作用完全相同。员,其作用完全相同。 方式方式1(*(指针变量(指针变量+i).成员名成员名 方式方式2(指针变量(指针变量+i) 成员名成员名 注意:这里的指针变量必须是指向某个数组首地址的,则上述两种引用方注意:这里的指针变量必须是指向某个数组首地址的,则上述两种引用方式均代表式均代表“数组名数组名i。成员名。成员名撩莱渊句腾询擎脆么浚镰氰岗戴满扇傣喝炔怀离扎汐裙蹄旧说越陷谆炙硅第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.4.3 在函数间传递结构型数据在函数间传递结构型数据1. 采用采用“全

37、局外部变量方式传递数据全局外部变量方式传递数据” 2. 采用采用“返回值方式传递数据返回值方式传递数据” 3. 采用采用“形式参数和实际参数结合的地址传递方形式参数和实际参数结合的地址传递方式双向传递数据式双向传递数据” 灼贬裸簿猿容港转醉歌浅汪胞甥羹裹暖置缠稀搔南裙朝黍华刮冯睡诵博戴第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.5 用指针处理链表用指针处理链表 我们知道用数组存放数据时,必须事先定义好数我们知道用数组存放数据时,必须事先定义好数组的大小,不能在程序中随便进行调整。比如有的组的大小,不能在程序中随便进行调整。比如有的班有班有100人,有的班只有人,有的班只有30人

38、,如果要用同一个数人,如果要用同一个数组先后存放不同班级的学生数据,则必须定义长度组先后存放不同班级的学生数据,则必须定义长度为为100的数组。如果事先难以确定一个班的最多人的数组。如果事先难以确定一个班的最多人数,则必须把数组定义的足够大,以存放任何班级数,则必须把数组定义的足够大,以存放任何班级的学生数据,这显然非常浪费存储空间。为此的学生数据,这显然非常浪费存储空间。为此C语语言提供了动态数组的构建,即链表。言提供了动态数组的构建,即链表。州处售抱渤匆史荤游祭谁抬装琐够赵召劈叮氓讯饱巨词淫韶详诡预澄宅殃第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.5.1 什么是链表什么是链

39、表 链表如同一条铁链一样,一环扣一环,中间是不能断开链表如同一条铁链一样,一环扣一环,中间是不能断开的。这好比幼儿园的老师带领孩子出去玩,老师牵着第一个的。这好比幼儿园的老师带领孩子出去玩,老师牵着第一个孩子的手,第一个孩子的另一只手牵着第二个孩子的手孩子的手,第一个孩子的另一只手牵着第二个孩子的手这就是一个这就是一个“链链”,最后一个孩子有一只手空着,他就是,最后一个孩子有一只手空着,他就是“链链尾尾”。要找这个队伍,就必须先找到老师,然后顺序找到每。要找这个队伍,就必须先找到老师,然后顺序找到每一个孩子。一个孩子。 链表是一种动态数据结构,在程序的执行过程中可以根据链表是一种动态数据结构,

40、在程序的执行过程中可以根据需要随时间系统申请存储空间,动态地进行存储空间的分需要随时间系统申请存储空间,动态地进行存储空间的分配。动态数据结构最显著的特点是包含的数据对象个数及其配。动态数据结构最显著的特点是包含的数据对象个数及其相互关系都可以按需要改变。常用的动态数据结构有链表、相互关系都可以按需要改变。常用的动态数据结构有链表、循环链表、双向链表三种。本章只介绍动态数据结构中最简循环链表、双向链表三种。本章只介绍动态数据结构中最简单的单链表的建立及其基本操作。单的单链表的建立及其基本操作。簿下秆补积辟癸炯哑供刷蛾氏怀感陷丧源涵翼籍废厢迟摈高相嗓二虽蛤碴第8章结构体共用体和枚举类型第8章结构

41、体共用体和枚举类型1.单链表的结构单链表的结构 链表有一个链表有一个“头指针头指针”head,它存放链表第一个结点的首地址,它存放链表第一个结点的首地址,它没有数据,只是一个指针变量。从图它没有数据,只是一个指针变量。从图8-2中我们看到它指向链表中我们看到它指向链表的第一个元素。链表的每一个元素称为一个的第一个元素。链表的每一个元素称为一个“结点结点”(node)。每。每个结点都分为两个域,一个是数据域,存放各种实际的数据,如个结点都分为两个域,一个是数据域,存放各种实际的数据,如学号学号num、姓名、姓名name、性别、性别sex、和成绩、和成绩score等。另一个域为指等。另一个域为指针

42、域,存放下一个结点的首地址,即指向下一个结点。链表中的针域,存放下一个结点的首地址,即指向下一个结点。链表中的每一个结点都是同一个结构类型。最后一个结点称为每一个结点都是同一个结构类型。最后一个结点称为“链尾链尾”,尾结点无后续点,因此不指向其他的元素,表尾结点的指针为空尾结点无后续点,因此不指向其他的元素,表尾结点的指针为空(NULL)。 褐迁叹丘赘猛赤丝卜奔柿伪俱铂症淬扛想长驮鹃纫昏头借楞秤钓星獭和狱第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2.链表结点的构成链表结点的构成 由于每个结点包含数据域或者指针域两部分内容,所以链表结点采用由于每个结点包含数据域或者指针域两部分内容

43、,所以链表结点采用结构体表示。例如链表结点的数据结构定义如下:结构体表示。例如链表结点的数据结构定义如下:struct node int num; char name10; float score; struct node *next; 在链表结构中,除了数据项成员之外,还应包含一个指向本身的指在链表结构中,除了数据项成员之外,还应包含一个指向本身的指针,该指针在使用时指向具有相同类型结构体的下一个结点。针,该指针在使用时指向具有相同类型结构体的下一个结点。 在链表结点的数据结构中,比较特殊的一点就是结构体内指针域的数在链表结点的数据结构中,比较特殊的一点就是结构体内指针域的数据类型使用了未定

44、义成功的数据类型。这是在据类型使用了未定义成功的数据类型。这是在C语言中唯一可以先使语言中唯一可以先使用后定义的数据结构。用后定义的数据结构。峨仇阴梗孟阵头于组铣瞧神掉纵藉惑虞疚梭旧呐缸欠吨末彼算捐兜听灾髓第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3.如何建立和输出一个简单静态链表 n【例【例 8.10】建立一个如图】建立一个如图8-3所示的简单链表,它由所示的简单链表,它由三个学生数据结点组成。请输出各结点中的数据。三个学生数据结点组成。请输出各结点中的数据。n分析:为方便操作,将学生定义为一个结构体类型分析:为方便操作,将学生定义为一个结构体类型student,它有三个成员分

45、别用来表示学生的学号、,它有三个成员分别用来表示学生的学号、姓名和下一个结点的地址。在程序中逐个输入各学姓名和下一个结点的地址。在程序中逐个输入各学生的数据,通过地址赋值操作建立链表。利用当型生的数据,通过地址赋值操作建立链表。利用当型循环用循环用printf语句逐个输出个结点中成员的值。语句逐个输出个结点中成员的值。甫蔼仪摘亮舜伐呼倘陡田繁嘿教杜批淌疽恭霜而傲鞍偏诛何渴材翌押惩咋第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型程序如下:程序如下:#includestruct student char no6; char name10; struct student *next;voi

46、d main() struct student A=“02001”,”tom”, B=“02002”,”jane”, C=“02003”,”henry”; struct srudent *head=NULL,*p; head=&A;A.next=&B;B.next=&C;C.next=NULL;p=head;while (p!=NULL) printf(“No:%stName:%sn”,p-no,p-name); p=p-next;在本例中,所有结点都是在程序中定义的、不是临时开辟的、用完后也不能释放,我们把在本例中,所有结点都是在程序中定义的、不是临时开辟的、用完后也不能释放,我们把这种链表

47、称为这种链表称为“静态链表静态链表”绣逆隋赊苔抽酗东钡目搐乒魁是股搬做偶暑蓝汾卫交皮虽柜众贞贩锯撤兰第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型4动态存储分配函数动态存储分配函数n所谓所谓“动态链表动态链表”就是链表的结构是动态分配和就是链表的结构是动态分配和存储的,在程序的执行过程中要根据需要随时向存储的,在程序的执行过程中要根据需要随时向系统申请存储空间,动态地进行存储空间的分配。系统申请存储空间,动态地进行存储空间的分配。在在C语言中,提供了一下函数完成存储空间的动语言中,提供了一下函数完成存储空间的动态分配和释放。态分配和释放。nmalloc函数函数ncalloc函数函数n

48、free函数函数菲殖寨扁攀嫌堰包泪痘划寅莉补怜撬称寂条梭乙绰营肝奏家涕氓牛夕措号第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型malloc函数n其函数原型为:其函数原型为:void * malloc(unsigned size)n 其作用是在内存的动态存储区中分配一个长度其作用是在内存的动态存储区中分配一个长度为为size的连续空间,并返回指向该空间起始地的连续空间,并返回指向该空间起始地址的指针。若分配失败(如系统不能提供所需址的指针。若分配失败(如系统不能提供所需内存),则返回空指针内存),则返回空指针NULL。牙律沮貉盎篱靶苯手哄学徒怨厌篡熄哄闹申的岭娜句堡滋坑叛砰钳莫巫琅第8

49、章结构体共用体和枚举类型第8章结构体共用体和枚举类型calloc函数n其函数原型为:其函数原型为:void * calloc(unsigned n,unsigned size)n 该函数有两个形参该函数有两个形参n和和size。其作用是在内存。其作用是在内存的动态存储区中分配的动态存储区中分配n个长度为个长度为size的连续空间,的连续空间,并返回指向该空间首地址的指针。如用并返回指向该空间首地址的指针。如用calloc(20,20)可以开辟可以开辟20个(每个大小为个(每个大小为20字节)字节)的空间,即空间总长为的空间,即空间总长为400字节。若分配失败,字节。若分配失败,则返回空指针则返

50、回空指针NULL。目没姿鼠馏互凭詹鬼腾阜歧风滋海闰楷预告毕蜒齿瓜负咐饮译豆午掣陌汕第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型free函数n其函数原型为:其函数原型为:void * free(void * ptr)n其作用是释放由其作用是释放由malloc、calloc等函数申请的内等函数申请的内存空间,使这部分内存区能够被其他变量所使存空间,使这部分内存区能够被其他变量所使用。用。ptr是最近一次调用是最近一次调用malloc()或或calloc()函数函数返回的值。返回的值。Free函数没有返回值。函数没有返回值。n在使用上述函数时要注意,函数的原型在文件在使用上述函数时要注意

51、,函数的原型在文件malloc.h和和stdlib.h中定义。在程序中必须包含中定义。在程序中必须包含这两个头文件。下面的程序就是这两个头文件。下面的程序就是malloc()和和free()两个函数配合使用的简单实例。两个函数配合使用的简单实例。喝噬丽窒未香钓拟陪击掇字州和伸总俞宽殃医久愤疤打蛊屉鱼冠力妈晌邀第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型【例 8.11】存储空间的动态分配。#include#include#includemain() char *str; if(str=(char*) malloc(10)=NULL) printf(“Not enough memory

52、 to allocate buffern”);exit(1);strcpy(str,”welcome”);printf(“String is %sn”,str);free(str); 本例中首先用本例中首先用malloc函数向内存申请一块内存区,并把首地址赋予指针变量函数向内存申请一块内存区,并把首地址赋予指针变量str,是,是str指向该区域。最后用指向该区域。最后用free函数释放函数释放str指向的内存空间。整个程序包含指向的内存空间。整个程序包含了申请内存空间、使用内存空间、释放内存空间三个步骤,实现存储空间的动了申请内存空间、使用内存空间、释放内存空间三个步骤,实现存储空间的动态分配

53、。态分配。脯刑陪溢妖齐吕窍牌狗吵喜凌块极鼠亩留赊揭披瞩邓订曼狗官英杰遍缉铃第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.5.2 动态链表的基本操作动态链表的基本操作n链表有五种基本操作:链表有五种基本操作:n建立建立n插入插入n删除删除n输出输出n查找查找洁悍鱼因插态刽饼燃涣忧慎绞泞烧杆哦仆扶歌绰缎予嗡钎叮熄痒绷邮娥剐第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型1.单链表的创建单链表的创建n建立动态链表就是建立结点空间、输入各结点数建立动态链表就是建立结点空间、输入各结点数据和进行结点链接的过程,也就是在程序执行过据和进行结点链接的过程,也就是在程序执行过程中从无到有

54、地建立起一个链表。程中从无到有地建立起一个链表。n通过以下实例来说明如何建立一个动态链表。通过以下实例来说明如何建立一个动态链表。 【例【例 8.12】建立一个链表存放学生数据。为简单起】建立一个链表存放学生数据。为简单起见,我们假定学生数据结构中有学号和年龄两项。见,我们假定学生数据结构中有学号和年龄两项。编写一个建立链表的函数编写一个建立链表的函数creat。母洽贾镶秤挂弓白施雷辣侍枯溜拌呛催宗疯担禾崭芽唆骄惜肋戳乾舌贷示第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型创建单链表的算法整乐的况制践骨圈终你紫沂戚抱刺约宪剪垣旺则矗桨闯淖讨曼饺贷靶祭衔第8章结构体共用体和枚举类型第8章

55、结构体共用体和枚举类型单链表创建过程分析茫蒂冲叼性犀里雌鸟圃瘟杨惑销捶韶耻啪把抽榴析反昂亿资畏彤房嫉殖椭第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型创建单链表实例程序清单#define LEN sizeof(struct stu)sruct stu /*结构结构stu定义为外部类型,方便程序中的各个函数使用定义为外部类型,方便程序中的各个函数使用*/ int num; int age; struct stu *next;struct stu *creat(void)/*creat函数用语动态建立一个有函数用语动态建立一个有n个结点的链表,返回与结点相同类型的指针个结点的链表,返回与

56、结点相同类型的指针*/ struct stu *p1,*p2,*head;/*head为头指针,为头指针,p2指向已建链表的最后一个结点,指向已建链表的最后一个结点,p1始终指向当前新开辟的结点始终指向当前新开辟的结点*/ int n=0; p1=p2=(struct stu *) malloc(LEN);/*申请新结点,长度与申请新结点,长度与stu长度相等;同时使指针变量长度相等;同时使指针变量p1、p2指向新结点指向新结点*/ scanf (“%d %d”,&p1-num,&p1-page); /*输入结点的值输入结点的值*/ head=NULL; while (p1-num!=0) /

57、*输入结点的数值不为输入结点的数值不为0*/ n+; if(n=1)head=p1; /*输入的结点为第一个新结点即空表,将输入的结点数据接入表头输入的结点为第一个新结点即空表,将输入的结点数据接入表头*/ else p2-next=p1;/*非空表即输入的结点不是第一个结点,将输入的结点数据接到表尾非空表即输入的结点不是第一个结点,将输入的结点数据接到表尾*/p2=p1;p1=(struct stu *)malloc(LEN); /*申请下一个新结点申请下一个新结点*/scanf(“%d %d”,&p1-num,&p1-page);p2-next=NULL;return(head); /*返

58、回链表的头指针返回链表的头指针*/猿遍浑俊侮歹趋嫂倚承喊酗悠瘁阁卸挡坐陡拽裹听达坪说舅炊肩砍吁酸萧第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型建立链表的具体步骤(1)定义链表的数据结构。)定义链表的数据结构。(2)创建一个空表。)创建一个空表。(3)利用)利用malloc()函数向系统申请分配一个结点。函数向系统申请分配一个结点。(4)若是空表,则将新结点接到表头;若是非)若是空表,则将新结点接到表头;若是非空表,则将新结点接到表尾。空表,则将新结点接到表尾。(5)判断一下是否有后续结点要接入链表,若)判断一下是否有后续结点要接入链表,若有则转到步骤(有则转到步骤(3),否则结束。

59、),否则结束。煮吻暂在蘑夯嘛抬佯座拿呆腋赛京吭讽胺伯茎肩摘芝挥庙诧遂抠误培冰谷第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2.单链表的插入 n链表的插入是指将一个结点插入到一个已有的链链表的插入是指将一个结点插入到一个已有的链表中。表中。 n【例【例 8.13】以前面建立的动态链表为例,编写一】以前面建立的动态链表为例,编写一个函数,使其能够在链表中指定的位置插入一个个函数,使其能够在链表中指定的位置插入一个结点。结点。儒崔型扳铭碎粒枕支谜闭颐寥貌柔奥难梅哲獭新芥促舵真帖锣喀义钙钻踌第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表插入实例分析n要在一个链表的指定位置插

60、入结点,要求链表本身必须已要在一个链表的指定位置插入结点,要求链表本身必须已按某种规律进行了排序。例如学生数据链表中,各结点的按某种规律进行了排序。例如学生数据链表中,各结点的成员项按学号由小到大顺序排列。如果要求按学号顺序插成员项按学号由小到大顺序排列。如果要求按学号顺序插入一个结点,则要将插入的结点依次与链表中各结点比较,入一个结点,则要将插入的结点依次与链表中各结点比较,寻找插入位置。结点可以插在表头、表中、表尾。结点插寻找插入位置。结点可以插在表头、表中、表尾。结点插入存在以下几种情况。入存在以下几种情况。1. 如果原表是空表,只需使链表的头指针如果原表是空表,只需使链表的头指针hea

61、d指向被插结点。指向被插结点。2. 如果被插结点值最小,则应插入第一个结点之前。将头指如果被插结点值最小,则应插入第一个结点之前。将头指针针head指向被插结点,被插结点的指针域指向原来的第一指向被插结点,被插结点的指针域指向原来的第一个结点。个结点。3. 如果在链表中某位置插入,使插入位置的前一结点的指针如果在链表中某位置插入,使插入位置的前一结点的指针域指向被插结点,使被插结点的指针域指向插入位置的后域指向被插结点,使被插结点的指针域指向插入位置的后一个结点。一个结点。4. 如果被插结点值最大,则在表尾插入,使原表尾结点指针如果被插结点值最大,则在表尾插入,使原表尾结点指针域指向被插结点,

62、被插结点指针域置为域指向被插结点,被插结点指针域置为NULL。绽瑚赔铱疚梧脯猴虹跪抓燥慈敬谰褒涸详椒饭夷赛糟宴屡蹈嵌氧辽檄嫁预第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表插入实例图形分析麻肋纪芒泣柏柳匀期亭堕郡条诀力沾弥寞槐窿迎粟苟孪哪沏则意久杖粗葡第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表插入实例操作步骤彪大凌磁锋单酬形硫喀枚悔天哮耿永撇粕醋茬罕疟皖蓉铺止缎绊男盾妆侗第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表插入实例程序清单struct stu *insert (struct stu *head,struct stu *p1) str

63、uct stu *p2,*p3; p2=head; if(head=NULL) /*空表插入空表插入*/ head=p1; p1-next=NULL;else while (p1-nump2-num)&(p2-next!=NULL) p3=p2; p2=p2-next; /*找插入位置找插入位置*/if ( p1-numnum) if (head=p2) head=p1; /*在第一结点之前插入在第一结点之前插入*/ else p3-next=p1; /*在其他位置插入在其他位置插入*/ p1-next=p2; else p2-next=p1;p1-next=NULL; /*在表末插入在表末插

64、入*/ return head; /*返回链表的头指针返回链表的头指针*/翼敏改掘休锌双芋凡块壁顶风遮郎围奥槛芥颈倡乱锑磁燃码信蹈墒颂凌履第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型链表插入操作的具体步骤n定义一个指针变量定义一个指针变量p1指向被插结点。指向被插结点。n首先判断链表是否为空,为空则使首先判断链表是否为空,为空则使head指向被指向被插结点。插结点。n链表若不是空,用当型循环查找插入位置。链表若不是空,用当型循环查找插入位置。n找到插入位置后判断是否在第一个结点之前插找到插入位置后判断是否在第一个结点之前插入,若是则使入,若是则使head指向被插入结点,被插结点指向

65、被插入结点,被插结点指针域指向原第一结点;否则在其他位置插入;指针域指向原第一结点;否则在其他位置插入;若插入的结点大于表中所有结点,则在表末插若插入的结点大于表中所有结点,则在表末插入。入。n函数返回值为链表的头指针。函数返回值为链表的头指针。渝剂宵攀写锁遁窖稍撰作很抚乎摈屠狮升鹃禽廷鬃坛场巢絮卫栗箩村剔旷第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3.单链表的删除单链表的删除 n链表中不再使用的数据,可以将其从表中删除并链表中不再使用的数据,可以将其从表中删除并释放其所占用的空间,但注意在删除结点的过程释放其所占用的空间,但注意在删除结点的过程中不能破坏链表的结构。中不能破坏链

66、表的结构。n【例【例 8.14】以前面建立的动态链表为例,编写一】以前面建立的动态链表为例,编写一个删除链表中指定结点的函数个删除链表中指定结点的函数delete1。昧花琢恶致钧宗闸赘像愁凭随尼蜀摘权盗浴版丙涨质皂为问矣休消栏淹釜第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表的删除实例分析n假设链表按学生的学号排列,当某结点的学号与假设链表按学生的学号排列,当某结点的学号与指定值相同时,将该结点从链表中删除。首先从指定值相同时,将该结点从链表中删除。首先从头到尾依次查找链表中给结点,并与各结点的学头到尾依次查找链表中给结点,并与各结点的学生学号做比较,若相同,则查找成功,否则,

67、找生学号做比较,若相同,则查找成功,否则,找不到结点。由于结点在链表中可以有三种不同位不到结点。由于结点在链表中可以有三种不同位置:位于开头,中间或结尾,因此从链表中删除置:位于开头,中间或结尾,因此从链表中删除一个结点主要分两种情况,即删除链表头结点和一个结点主要分两种情况,即删除链表头结点和非表头结点。非表头结点。1. 如果被删除的结点是表头结点,使如果被删除的结点是表头结点,使head指向第二指向第二个结点。个结点。2. 如果被删除的结点不是表头结点,使被删结点的如果被删除的结点不是表头结点,使被删结点的前一结点指向被删结点的后一结点。前一结点指向被删结点的后一结点。篮仅淖滁功循影痉雁照

68、葱供晃汽情诱勿邹场槐瓣冯踢乌劝喇泡遵惫桑碍就第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表的删除实例图形分析逗骏哆殿犁凭妓口旺旧剧蔼雪曙抗厄冷缮汇龙必碗翅亲英讥嚣登购辅敖庐第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表 的删除实例操作步骤轻再喧饥那黎岸隘猫致脂惩堑发拿斟地盖晓硒袒琶琶竣亥趋僵诽巧百谓漠第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表的删除实例程序清单struct stu * delete ( struct stu *head,int num) /*以以head为头指针删除为头指针删除num所在结点所在结点*/ struct stu

69、*p1,*p2; if (head=NULL) /*如为空表,输出提示信息如为空表,输出提示信息*/ printf(“nempty list!n”); goto end;p1=head;while ( p1-num!=num & p1-next!=NULL)/*当不是要删除的结点,而且也不是最后一个结点时,继续循环当不是要删除的结点,而且也不是最后一个结点时,继续循环*/p2=p1;p1=p1-next; /*p2指向当前结点,指向当前结点,p1指向下一结点指向下一结点*/if (p1-num=num) if (p1=head) head=p1-next;/*如找到被删结点,且为第一结点,则使

70、如找到被删结点,且为第一结点,则使head指向第二结点,否则使指向第二结点,否则使p2所指结点的指针指向所指结点的指针指向下一结点下一结点*/else p2-next=p1-next;free(p1);printf (“ The node is deletedn”); else printf (“The node not been found!n”); end: return (head);锣壬壁啃饯枢卿盏寻嗡希骏梨辛桩镀纹则旺综失墙列芋秒钨纽缴蛔凹希谋第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型链表删除操作的具体步骤 n定义一个指针变量定义一个指针变量p指向链表的头结点。指向链表

71、的头结点。n用循环从头到尾依次查找链表中各结点并与用循环从头到尾依次查找链表中各结点并与各结点的学生学号做比较,若相同,则查找各结点的学生学号做比较,若相同,则查找成功退出循环。成功退出循环。n判断该结点是否为表头结点,如果是使判断该结点是否为表头结点,如果是使head指向第二个结点,如果不是使被删结点的前指向第二个结点,如果不是使被删结点的前一结点指向被删结点的后一结点。同时结点一结点指向被删结点的后一结点。同时结点个数减个数减1。腋颖效皿丢箱俩弱银殉恐忆参前浙臆徘敛茹采剪潦痕妆脂硫防暇勘纯媒仗第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型4.单链表的输出 n链表的输出比较简单,只

72、要将链表中的各个结链表的输出比较简单,只要将链表中的各个结点数据依次输出即可点数据依次输出即可 n【例【例 8.15】编写一个输出链表的函数】编写一个输出链表的函数print。汞钉嗜划仪酉等律闷讽湖碌痊仙晴帧整番龙恼屑伴陆饵外些喘犯他涝沈偏第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型n设立一个指针变量设立一个指针变量p,先指向链表的头结点,先指向链表的头结点,输出该结点的数据域,然后使指针输出该结点的数据域,然后使指针p指向下一指向下一个结点,重复上述工作,直到链表尾部。具体个结点,重复上述工作,直到链表尾部。具体算法如图算法如图8-9所示。所示。 买票估籽逸作纵尉枕唆镇造矽老劈怔

73、汪钾牺纹毯柑刀孩藩软哆焚昼兰晕磅第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型单链表的输出实例程序清单#define LEN sizeof (struct stu)struct stu int num; int age; struct stu *next;void print ( struct stu *head) /*print函数用于输出以函数用于输出以head为头的链表各为头的链表各结点的值结点的值*/ struct stu *p; p=head; /*取得链表的头指针取得链表的头指针*/ while (p!=NULL) printf ( “%6d%6d”,p-num,p-pa

74、ge); /*输出链表结点的值输出链表结点的值*/p=p-next; /*使指针变量使指针变量p指向下一个结点,跟踪链表增长指向下一个结点,跟踪链表增长*/踏躬颈弃步掇墒视是簧粳惜蹄取翘枚嚎瞳庄桑泡腕糜找丑认纷馁函窟普举第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型链表输出操作的具体步骤n定义一个指针变量定义一个指针变量p。n使使p指向链表的头结点。指向链表的头结点。n若是非空表,输出该结点的数据域;若空表若是非空表,输出该结点的数据域;若空表则退出。则退出。n使指针使指针p指向下一个结点。指向下一个结点。n重复上述操作直到链表尾部。重复上述操作直到链表尾部。喧靠嗽判魏渝觉潜为遭妖编

75、席绎吸慢寒苍帝言将枉穗孤堑蕴舌晤糟旁算碗第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型链表综合实例n【例【例 8.16】在前面学习的建立链表,输出链表,】在前面学习的建立链表,输出链表,删除结点,插入结点操作的基础上,试编一主函删除结点,插入结点操作的基础上,试编一主函数将以上的建立链表,输出链表,删除结点,插数将以上的建立链表,输出链表,删除结点,插入结点的函数组织在一起,并输出全部结点的值。入结点的函数组织在一起,并输出全部结点的值。婿露绚碑好炬韩住韵涸并劫糠缮臣臆绝搓健脑疯坊饥旗桃瘸敛屉邱沿蕾颤第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型综合实例程序清单#defin

76、e NULL 0main () struct stu *head; struct stu *stu; int del_num; printf (“input records:n”); head=creat(); /*建立链表,并返回表头建立链表,并返回表头*/ print (head); /*输出链表输出链表 */ printf (“nInput the deleted number:”); scanf (“%d”,&del_num);腻究按树咒揪笑幻孙陶蔬凡缚赶而地痰巫史涎意稿星紫仆灾酉拣挪脆鞍违第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型综合实例程序清单(续)while (de

77、l_num!=0) head=delete1 (head,del_num); /*从链表中删除从链表中删除del_num结点结点*/print (head); /*输出链表输出链表 */ printf (“nInput the deleted number:”); scanf (“%d”,&del_num);printf (“nInput the inserted record:”);stu=(struct stu *)malloc(LEN);scanf (“%d,%d”,&stu-num,&stu-age);while (stu-num!=0) head=insert (head,stu);

78、 /*在链表中插入一节结点在链表中插入一节结点stu*/ print (head); /*输出链表输出链表 */ printf (“nInput the inserted record:”); stu=( struct student *)malloc (LEN); scanf (“%d,%d”,&stu-num,&stu-age); free (stu) /*对于对于num=0的结点,未插入,应删除其空间的结点,未插入,应删除其空间*/脐秦汇趟背它了眷结遭白说曾蓖船你毡钉信柜翁赔欣扩芯娇恭剥衬寺烁谨第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.6 共共 用用 型型n共用型和结构

79、型的比较共用型和结构型的比较它惫豢做璃照薄雷霹熟喜麦侗稚挑费第纂辑舷侥颖堤炸蜘绣且敌漠船驹赫第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.6.1 共用型的定义共用型的定义nunion共用型名共用型名 数据类型数据类型1 成员名成员名1; 数据类型数据类型2 成员名成员名2; 数据类型数据类型n 成员名成员名n; ;n注意在右花括号的后面有一个语句结束符分号。注意在右花括号的后面有一个语句结束符分号。尤辽白浩蛋闷技外阁纶菜在孟及编店稻汇币称猩巧辨傅壳游齿氖念昭韩咎第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型共用型的定义实例共用型的定义实例n例如:为了节省内存,可以将不同

80、的三个数组定义在一个共例如:为了节省内存,可以将不同的三个数组定义在一个共用型中,总计可节省用型中,总计可节省300个单元:个单元:n union c_i_f char c1100; /*该成员占用该成员占用100个单元个单元*/ int i2100; /*该成员占用该成员占用200个单元个单元*/ float f3100; /*该成员占用该成员占用400个单元个单元*/ ; /*该共用型数据共用该共用型数据共用400个单元个单元*/n需要提醒读者注意的是,共用型数据中每个成员所占用的内需要提醒读者注意的是,共用型数据中每个成员所占用的内存单元都是连续的,而且都是从分配的连续内存单元中第一存单

81、元都是连续的,而且都是从分配的连续内存单元中第一个内存单元开始存放的。所以,对共用型数据来说,所有成个内存单元开始存放的。所以,对共用型数据来说,所有成员的首地址都是相同的。这是共用型数据的一个特点。员的首地址都是相同的。这是共用型数据的一个特点。扁湖哎殊笑宪椅奇华污陷宋酗复钦典铂懒麓嘎统耍因洽捍巩界伺瓣繁淹捶第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.6.2 共用型变量的定义共用型变量的定义n定义方法基本上与结构型相同,也存在以下三定义方法基本上与结构型相同,也存在以下三种方法,但不能在定义时进行初始化。种方法,但不能在定义时进行初始化。1. 先定义共用型,然后定义变量与数组

82、。先定义共用型,然后定义变量与数组。2. 定义共用型的同时定义变量与数组定义共用型的同时定义变量与数组3. 定义无名称的共用型同时定义变量与数组定义无名称的共用型同时定义变量与数组 渊歧炒酣匀迂洲声翰彰浸揪立结保暮采搓硷榨寨棍药缆刀赞喷憎谈姬易斌第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型1.先定义共用型,然后定义变量u1与数组u25。union u int i_a10; /*该成员占用该成员占用20个单元个单元*/ char c_a34; /*该成员占用该成员占用12个单元个单元*/ long l; /*该成员占用该成员占用4个单元个单元*/ double d; /*该成员占用该

83、成员占用8个单元个单元*/; /*该共用型数据共占用该共用型数据共占用20个单元个单元*/union u u1,u25;咱挠篷缮呼敛退铝赛烹瘩途懦偿鸟仿茨胺求谢窍寇间陡宵迈备违映傲县郧第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2.定义共用型的同时定义变量u1与数组u25 union u int i_a10; /*该成员占用该成员占用20个单元个单元*/ char c_a34; /*该成员占用该成员占用12个单元个单元*/ long l; /*该成员占用该成员占用4个单元个单元*/ double d; /*该成员占用该成员占用8个单元个单元*/ u1,u25; 台衬链五豆岗陋办邦涸

84、炕捡塞灸姨摸渠苑伸凶告烷悲情烦禁矫笆蔚翁雅意第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3. 定义无名称的共用型同时定义变量u1与数组u25 union /*无名称无名称*/int i_a10; /*该成员占用该成员占用20个单元个单元*/ char c_a34; /*该成员占用该成员占用12个单元个单元*/ long l; /*该成员占用该成员占用4个单元个单元*/ double d; /*该成员占用该成员占用8个单元个单元*/ u1,u25; 未蓖疯兜班睫耪兴控愤涤实滋蒙甭皖婴纂船巧鲍洲泵哟烤掣覆贫彭免诲忿第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.6.3 共用

85、型变量的引用共用型变量的引用n共用型变量或数组元素成员的引用格式如下:共用型变量或数组元素成员的引用格式如下: 共用型变量名共用型变量名.成员名成员名n共用型变量成员地址的引用和指针变量的使用共用型变量成员地址的引用和指针变量的使用格式如下:格式如下: 指针变量指针变量=&共用型变量名共用型变量名.成员名成员名n共用型变量地址的引用和指针变量的使用格式共用型变量地址的引用和指针变量的使用格式如下:如下: 指针变量指针变量=&共用型变量名共用型变量名招涡掐焦扮桑洽汾呛变和舍瞄唤若到越桃桥善纂核埔恃婶储送客莹半耍色第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.7 枚举型枚举型n顾名思

86、义,就是把有限的数据一一例举出来,例顾名思义,就是把有限的数据一一例举出来,例如:如:n一个星期一个星期7天天n性别只有性别只有”男男”和和”女女” n中国有中国有23个省,个省,5个自治区,个自治区,4个直辖市,个直辖市,2个特别个特别行政区等。行政区等。n如下图:在填写用户资料中的所在城市时,把中如下图:在填写用户资料中的所在城市时,把中国的国的23个省,个省,5个自治区,个自治区,4个直辖市,个直辖市,2个特别行个特别行政区都列举出来,供注册者选择,这样有利于数政区都列举出来,供注册者选择,这样有利于数据的规范且不会出错。枚举型和结构型、共用型据的规范且不会出错。枚举型和结构型、共用型一

87、样,也是一种用户自定义的数据类型,在使用一样,也是一种用户自定义的数据类型,在使用时必须先定义后使用。时必须先定义后使用。瓤春嫁俺绍腿贡碟撮舒檄人远尚抉帖翻逊聊伏姻喀忘广枝索觉酵梯京把验第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型臻俯紧逆轻域驼贴佐平逢墙忻抨矮至弛迭童睛霹竭疤童杖敞盅钱恩稽炬烫第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.7.1 枚举型的定义枚举型的定义nenum 枚举型名枚举型名n 枚举常量枚举常量1,枚举常量,枚举常量2,枚举常量枚举常量n;n注意在右花括号的后面有一个语句结束符分号。注意在右花括号的后面有一个语句结束符分号。n其中:枚举型名是用户

88、取的标识符;其中:枚举型名是用户取的标识符;n 枚举常量是用户给常量取的标识符。枚举常量是用户给常量取的标识符。n该语句定义了一个名为该语句定义了一个名为“枚举型名枚举型名”的枚举类型,的枚举类型,该枚举型中含有该枚举型中含有n个枚举常量,每个枚举型常量均个枚举常量,每个枚举型常量均有值。有值。C语言规定枚举常量的值依次等于语言规定枚举常量的值依次等于0、1、2、n-1.陀袭伶凤葡畏柳焕赡沿绑空褒蓄移天阁瘴素坛腹耐温谭生烬蝇琉抖凳漳装第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型枚举型定义实例例如:定义一个表示星期的枚举型:例如:定义一个表示星期的枚举型: enum week sun

89、,mon,tue,wed,thu,fri,sat; 定义的这个枚举型共有定义的这个枚举型共有7个枚举常量,它们的值依次为个枚举常量,它们的值依次为0、1、2、3、4、5、6。 C语言规定,在定义枚举型时,可以给枚举常量赋初值,方语言规定,在定义枚举型时,可以给枚举常量赋初值,方法是在枚举常量的后面跟上法是在枚举常量的后面跟上“=整型常量整型常量”。例如:表示三原色的枚举型可定义如下:例如:表示三原色的枚举型可定义如下: enum color1 red=2,yellow=4,blue=7; 则枚举常量则枚举常量red的值为的值为2,yellow的值为的值为4,blue的值为的值为7。宵罢阻圣瘦捐

90、觉修恢扶蹭元俩际禄吼涣岁疆侯患脊吾霉廖睹阀揣馋歹玫悄第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.7.2 枚举型变量的定义枚举型变量的定义n当某个枚举型定义后,可以用这种枚举型来定义变量、数组。定义的方当某个枚举型定义后,可以用这种枚举型来定义变量、数组。定义的方法有三种。法有三种。1. 先定义枚举型,后定义枚举型变量、数组先定义枚举型,后定义枚举型变量、数组nenum colornred,yellow,blue;nenum color color_1,color_22; n/*定义一个枚举型变量定义一个枚举型变量color1和具有两个元素的数组和具有两个元素的数组color_2

91、*/2. 定义枚举型的同时定义枚举型变量、数组定义枚举型的同时定义枚举型变量、数组nenum colornred,yellow,blueenum color color_1,color_22; n/*定义一个枚举型变量定义一个枚举型变量color1和具有两个元素的数组和具有两个元素的数组color_2*/3. 定义无名称的枚举型的同时定义枚举型变量、数组定义无名称的枚举型的同时定义枚举型变量、数组nenum nred,yellow,blue enum color color_1,color_22; n/*定义一个枚举型变量定义一个枚举型变量color1和具有两个元素的数组和具有两个元素的数组c

92、olor_2*/疽芒福辑悸乳枯界圈包歹蚀冠躺甭建塌佣柑逼筏诧吕嗜泼簧粉和液腺简代第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.7.3 枚举型变量的引用枚举型变量的引用n给变量或数组元素赋值,格式为:给变量或数组元素赋值,格式为: 枚举型变量或数组元素枚举型变量或数组元素=同一种枚举型常量名同一种枚举型常量名 enum color red,yellow,blue c_1; c_1=yellow; /*赋值赋值*/n 在循环中用枚举变量或数组元素控制循环在循环中用枚举变量或数组元素控制循环 enum color red,yellow,bluec_1; int k=0; for(c_1

93、=red;c_1=blue;c_1+) k+; printf(“k=%dn”,k);耙乘维女摆熄杨熙栈肄馋莹饲均耸尘摘续旱适旬镭巡丧捏剩兹荧伞温钨伦第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型8.8 用户自定义类型用户自定义类型nC语言允许用户定义自己习惯的数据类型名称语言允许用户定义自己习惯的数据类型名称,来来替代系统默认的基本类型名称、数组类型名称、替代系统默认的基本类型名称、数组类型名称、指针类型名称和用户自定义的结构型名称、共用指针类型名称和用户自定义的结构型名称、共用型名称、枚举型名称等。型名称、枚举型名称等。 n用户字定义类型名的方法是通过下列定义语句实用户字定义类型名

94、的方法是通过下列定义语句实现的:现的:typedef 类型名类型名1 类型名类型名2;奈垫邦慑壬养眉剐尉漓惜嘉搞还陆实孙擦濒扁锅勒塞嚷喂撬忿咸哆偶排嚎第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型1. 基本类型的自定义基本类型的自定义n对所有系统默认的基本来性可以利用下面的自定义类型语对所有系统默认的基本来性可以利用下面的自定义类型语句来重新定义类型名。句来重新定义类型名。n【例【例 8.22】基本类型自定义例。】基本类型自定义例。 typedef float REAL; /*定义单精度实型为定义单精度实型为REAL*/ typedef char CHARACTER /*定义字符型为

95、定义字符型为GHARACTER*/ main() REAL f1; /*相当于相当于float f1;*/ CHARACTER c1; /*相当于相当于char c1,*/ 乌馆辊卖哄起疏腋厨拇痰保辟访剧娥狮息厅答镶匪锄吓谢岗应怯频溶酞乓第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型2.数组类型的自定义数组类型的自定义 n对数组类型可以利用下面的自定义类型语句来定义一个类对数组类型可以利用下面的自定义类型语句来定义一个类型名型名 ntypedef 类型说明符类型说明符 用户类型名用户类型名数组长度数组长度n【例【例 8.23】数组类型自定义例。】数组类型自定义例。typedef fl

96、oat F_ARRAY20; typedef char C_ARRAY10;main() F_ARRAY f1,f2; /*相当于相当于 float f120, f220*/C_ARRAY name,department; /*相当于相当于char name10,department10*/棋纷逐奴修溃弊诈须僻旁仲酶料疚滇哆勇蔚龙酮卸芍凝谎痒盘注巫翠坤涂第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型3.结构型、共用型的自定义结构型、共用型的自定义 n对程序中需要的结构型可以利用下面的自定义类型语句来定义一个类型名对程序中需要的结构型可以利用下面的自定义类型语句来定义一个类型名 nty

97、pedef struct n类型说明符类型说明符 成员名成员名1;n 类型说明符类型说明符 成员名成员名2;.n用户类型名用户类型名;n【例【例 8.24】结构型自定义例。】结构型自定义例。typedef struct long num;char name 10;char sex;STUDENT; main()STUDENT stu1,stu10; /*相当于相当于struct long num; char name 10; Char sex; stu1,stu10;*/逆颐俗截沮忌湾嘱吞格蚀点黍遣淬其疚条汰烩贩器抵氦炔著恤示钳填篆棉第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型4.

98、指针型的自定义指针型的自定义 n对某种数据类型的指针型可以利用下面的自定义类对某种数据类型的指针型可以利用下面的自定义类型语句来定义一个类型名型语句来定义一个类型名 ntypedef 类型说明符类型说明符 *用户类型名;用户类型名;n【例【例 8.25】指针类型自定义例】指针类型自定义例typedef int *POINT_I; typedef char *POINT_C; main() POINT_I p1,p2; /*相当于相当于int *p1,*p2*/POINT_C p3,p4; /*相当于相当于char *p3,*p4*/操补唉汾芬巳实篇钦趋哇晕衅颊了踏熙乙摹霸琢渭阜拭琴谷普允套鳞洼

99、峰第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型小小 结结n本章详细介绍了结构型变量的定义、初始化、本章详细介绍了结构型变量的定义、初始化、引用等方法,同时介绍了另外一种用于节省内引用等方法,同时介绍了另外一种用于节省内存的构造型数据:共用型,最后简单介绍了枚存的构造型数据:共用型,最后简单介绍了枚举型数据的使用。举型数据的使用。n学习本章时应牢记,结构型、共用型是一种用学习本章时应牢记,结构型、共用型是一种用户自定义类型,因此在使用前必须先定义。同户自定义类型,因此在使用前必须先定义。同时掌握其引用的格式。时掌握其引用的格式。肛凤点梆杖阎柳鞘益肉摹署劈廓穿骄摄激界众窑夜镍扯永餐晨实月话祸宛第8章结构体共用体和枚举类型第8章结构体共用体和枚举类型

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号