1、第九章第九章 结构体、共用体、枚举结构体、共用体、枚举湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院湖南省普通高等学校省级精品课程湖南省普通高等学校省级精品课程C语言程序设计语言程序设计湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院目录目录问题提出问题提出 结构体结构体 共用体共用体 枚举类型枚举类型 程序应用综合举例程序应用综合举例 总结总结 湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院什么是结构?结构与数组有什么差别?什么是结构?结构与数组有什么差别?有几种结构的定义形式,它们之间有什么不同?有几种结构的定义形式,它们之间有什么不同?什么是结构的嵌套?什么是
2、结构的嵌套?什么是结构变量和结构成员变量,如何引用结构成员变量?什么是结构变量和结构成员变量,如何引用结构成员变量?结构变量如何作为函数参数使用?结构变量如何作为函数参数使用?什么是结构数组,如何定义和使用结构数组?什么是结构数组,如何定义和使用结构数组?什么是结构指针,它如何实现对结构分量的操作?什么是结构指针,它如何实现对结构分量的操作?*结构指针是如何作为函数的参数的?结构指针是如何作为函数的参数的?*如何建立单向链表并实现插入、删除以及查找操作?如何建立单向链表并实现插入、删除以及查找操作?什么是共用体?共用体与结构体有什么区别?什么是共用体?共用体与结构体有什么区别?什么是枚举类型?
3、枚举类型数据如何引用?什么是枚举类型?枚举类型数据如何引用?学习目标、重点学习目标、重点 、难点难点*湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院9.1 问题的提出问题的提出v 在程序里表示一个人(学号、姓名、各科成绩、在程序里表示一个人(学号、姓名、各科成绩、)?)?v 想表示多个人呢?想表示多个人呢?解决方案解决方案char studentId3010=01,02,03,04;char studentName3020=张三张三,李四李四,王五王五,刘娟刘娟;float scoreComputer30=88.5,86.5,75,68.5;float scoreEnglish30=
4、78,75.5,65.5,82;float scoreMath30=78,75.5,65,82.5;1.使用数组01020304张三张三李四李四王五王五刘娟刘娟88.586.57568.57888827286928578分配内存不集中,寻址效率不高分配内存不集中,寻址效率不高不能建立数组间的关系不能建立数组间的关系对数组进行赋初值时,容易发生错位对数组进行赋初值时,容易发生错位2.使用多维数组张三李四王五刘娟88.586.57568.5010203047888827286928578C 语言不允许一个数组语言不允许一个数组包含多种数据类型包含多种数据类型怎么解决呢?湖南工业大学计算机与通信学院
5、湖南工业大学计算机与通信学院希望的内存分配图希望的内存分配图 01张三张三88.5787802李四李四86.575.575.503王五王五7565.56504刘娟刘娟68.58282.5人们设想找到一种数据类型,把学生的信息当一个整体人们设想找到一种数据类型,把学生的信息当一个整体来存储,即这个整体中元素的数据类型可以不同。这个来存储,即这个整体中元素的数据类型可以不同。这个数据类型即结构体数据类型即结构体,可以将不同类型的数据组合成一个,可以将不同类型的数据组合成一个整体,用来表示简单类型无法描述的复杂对象,同时可整体,用来表示简单类型无法描述的复杂对象,同时可以用结构体来定义用户自己的数据
6、类型。以用结构体来定义用户自己的数据类型。扩展开来,在现实中,扩展开来,在现实中,几个数据之间有着密切联系,它几个数据之间有着密切联系,它们用来描述事物的几个方面,但它们不属于同一类型,们用来描述事物的几个方面,但它们不属于同一类型,这时可以用结构体数据类型。也就是说结构体为程序员这时可以用结构体数据类型。也就是说结构体为程序员提供了一种封装一组相关数据元素的简便方法。提供了一种封装一组相关数据元素的简便方法。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院9.1 问题的提出问题的提出又如,在学生信息管理系统中填又如,在学生信息管理系统中填加个属性:是否是中共党员,如加个属性:是否是中
7、共党员,如果不是属性的值为果不是属性的值为0(int),如),如果是属性的值为入党的时间果是属性的值为入党的时间(char)。在某一时间,属性只有在某一时间,属性只有一种值,而且数据类型不同,一种值,而且数据类型不同,这这种情况用什么数据类型描述呢?种情况用什么数据类型描述呢?对于这种应用,对于这种应用,C C语言引入了共用体类型。语言引入了共用体类型。共用体是一种同一存储区域由不同类型变量共享的数据共用体是一种同一存储区域由不同类型变量共享的数据类型,它提供类型,它提供种方法能在同一存储区中操作不同类型种方法能在同一存储区中操作不同类型的数据,也就是说共用体采用的是覆盖存储技术,准许的数据,
8、也就是说共用体采用的是覆盖存储技术,准许不同类型数据互相覆盖。不同类型数据互相覆盖。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院9.1 问题的提出问题的提出此时用整型数来表示这些变量的取值,其直观此时用整型数来表示这些变量的取值,其直观性很差,如在程序中使用性很差,如在程序中使用1,对于非编程者来说,对于非编程者来说,它是代表星期一呢?还是一月份?很难区分。它是代表星期一呢?还是一月份?很难区分。为提高程序的可读性,引入非数值量,即一些为提高程序的可读性,引入非数值量,即一些有意义的符号是非常必要的。有意义的符号是非常必要的。另外,在实际应用中,有些变量的取值另外,在实际应用中,有
9、些变量的取值范围是有限的,仅可能只有几个值范围是有限的,仅可能只有几个值。一个星期一个星期7天,一天,一年年12个月个月 一副扑克有一副扑克有4种花色,每种花色,每一花色有一花色有13张牌张牌 对于这种应用,对于这种应用,C语言引入语言引入枚举类型枚举类型,所谓,所谓“枚举枚举”,就是将变量可取的值一一列举出来。,就是将变量可取的值一一列举出来。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院从基本数据类型、复合数据类型到抽象数据类型从基本数据类型、复合数据类型到抽象数据类型v计算机本身是没有数据类型的概念的计算机本身是没有数据类型的概念的n内存里存储的内容,你认为它代表什么,它就代表
10、什么v高级语言设计了基本数据类型:整型、浮点型、字高级语言设计了基本数据类型:整型、浮点型、字符型等。不同的语言也会定义不同的基本类型符型等。不同的语言也会定义不同的基本类型n基本数据类型并不能方便地解决所有问题v复合数据类型是基本数据类型迭代派生而来复合数据类型是基本数据类型迭代派生而来n典型的代表就是“结构”,数组、指针也可算作此类v抽象数据类型抽象数据类型(ADT)(ADT)在复合数据类型的基础上增加在复合数据类型的基础上增加了对数据的操作了对数据的操作v抽象数据类型进而进化为抽象数据类型进而进化为“类类”n这是一个跨时代的进步湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院 结
11、构成员;结构名structnodechar id20;char name20;float score3;C 语言中的有效数据类型9.2 9.2 结构体结构体9.2.1 结构体类型结构体类型上述学生基本信息(学号、姓名、各科成绩)的例子,上述学生基本信息(学号、姓名、各科成绩)的例子,C语言程语言程序可用结构体定义为:序可用结构体定义为:湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院9.2.1 9.2.1 结构体类型结构体类型结构体类型的定义structstruct 结构体名结构体名 类型标识符类型标识符 成员名成员名1 1;类型标识符类型标识符 成员名成员名2 2;struct是是关
12、键字关键字,不能省略不能省略合法标识符合法标识符可省略:无名结构体可省略:无名结构体成员类型可以是基本成员类型可以是基本类型或构造类型类型或构造类型必须有分号必须有分号湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院struct node char id20;char name20;float score3;idnamenodev结构定义并不预留内存v结构定义放置在程序的开始部分,位于头文件声明之后 scorev结构定义仅描述了一个结构的形式。如果要在程序里使用结构,需要声明结构变量。9.2.1 9.2.1 结构体类型结构体类型湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院s
13、truct address char city10;char street20;int code;int zip;嵌套结构嵌套结构struct nest_friendslist char name10;int age;struct address addr;char telephone13;在定义嵌套的结构类型在定义嵌套的结构类型时,必须先定义成员的时,必须先定义成员的结构类型,再定义主结结构类型,再定义主结构类型。构类型。姓名年龄通信地址联系电话城市街道门牌号邮编湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院9.2.29.2.2结构体类型变量结构体类型变量1.1.结构体类型变量的定
14、义结构体类型变量的定义 结构体变量的定义有以下几种形式:结构体变量的定义有以下几种形式:单独定义:单独定义:先先定义结构体定义结构体类型类型,后后定义结构体定义结构体变量变量 struct node char id20;char name15;int score3;struct node student1,student2;直接定义:直接定义:在定义结构体类型同在定义结构体类型同时定义结构体变量时定义结构体变量 struct node char id20;char name15;int score3;student1,student2;结构体类型名结构体类型名node可以不写可以不写湖南工业大
15、学计算机与通信学院湖南工业大学计算机与通信学院内存student1struct node student1=01,Yao Ming,80,90.5;结构体类型变量的初始化结构体类型变量的初始化01Yao Ming80注意:v赋值的顺序应与成员声明时的顺序一样v允许初始化语句中的值的数目比结构成员数目少90.5初始化一般形式:结构体类型名 结构体变量=初值表;湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院结构体变量的引用结构体变量的引用结构体变量的引用原则结构体变量的引用原则结构体变量不能整体输入输出,要通过成员运算符“.”,逐个访问其成员,且访问的格式为:struct date in
16、t year;int month;int day;struct date birth;printf(%d,%d,%dprintf(%d,%d,%d,birthbirth);printf(%d,%d,%dprintf(%d,%d,%d,birth.yearbirth.year,birth.month,birth.daybirth.month,birth.day);结构体变量.成员“.”是成员运算符,是成员运算符,优先级最高优先级最高湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院如果某成员本身又是一个结构类型,则只能通过多级的分量运如果某成员本身又是一个结构类型,则只能通过多级的分量运算
17、,对最低一级的成员进行引用。算,对最低一级的成员进行引用。引用结构变量引用结构变量studentstudent中的中的birthdaybirthday成员的格式分别为:成员的格式分别为:student.birthday.yearstudent.birthday.yearstudent.birthday.monthstudent.birthday.monthstudent.birthday.daystudent.birthday.day结构体变量的引用struct std_info int num;char name20;char sex;float score;struct date birt
18、hday;student;struct date int year;int month;int day;num name sex score birthdaystudent:对最低一级成员,可像同类型的普通变量一样,进行相对最低一级成员,可像同类型的普通变量一样,进行相应的各种运算。应的各种运算。结构变量结构变量.成员成员.子成员子成员.最低级子成员最低级子成员湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院student2student2.id=02;student2.name=Zhang Zi Liang;student2.score1=88;printf(请输入成绩:请输入成绩:
19、n);scanf(%f,&student2.score2);结构变量赋值结构变量赋值02Zhang Zi Liang 88用输入语句或赋值语句来给结构变量的各个成员赋值7878student3=student2;student302Zhang Zi Liang 8878结构变量的整体赋值湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院例例9-19-1学生的基本信息包括学号、姓名、学生的基本信息包括学号、姓名、3 3门成绩、平均分、总分。输入一门成绩、平均分、总分。输入一个学生的前个学生的前3 3项基本信息,计算平均分和总分并输出。项基本信息,计算平均分和总分并输出。printf(请输入
20、姓名:请输入姓名:);gets(stu1.name);for(int i=0;i3;i+)printf(请输入请输入%s 成绩成绩:,CLASSNAMEi);scanf(%f,&stu1.scorei);sum+=stu1.scorei;stu1.sum=sum;stu1.ave=sum/3;printf(学号学号:%s姓名姓名:%s总成绩总成绩:%f 平均成绩平均成绩%.2fn,stu1.id,stu1.name,stu1.sum,stu1.ave);for(i=0;i CLASS;i+)printf(%s 成绩成绩:%.2fn,CLASSNAMEi,stu1.scorei);分析分析 :定
21、义一个结构体类型对应于学生的基本信定义一个结构体类型对应于学生的基本信息。输入学生信息,即对结构体变量的各息。输入学生信息,即对结构体变量的各成员项逐个赋值,总分我们利用循环结构成员项逐个赋值,总分我们利用循环结构进行计算。输出学生信息,我们用进行计算。输出学生信息,我们用printf()格式控制输出。格式控制输出。#include#define CLASS 3struct node char id10;/学号学号 char name15;/姓名姓名 float score3;/成绩成绩 float sum;/总分总分 float ave;/平均分平均分;char CLASSNAMECLASS
22、30=计算机计算机,英语英语,数学数学;void main()struct node stu1;float sum=0;printf(请输入学号:请输入学号:);gets(stu1.id);湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院思考题思考题9-19-1:v在上面的程序中,考虑如果把在上面的程序中,考虑如果把gets(stu1.name)gets(stu1.name)语句语句改为改为scanf(%s,stu1.name)scanf(%s,stu1.name)有什么不同?有什么不同?v什么是结构体类型?什么是结构体变量?结构体类什么是结构体类型?什么是结构体变量?结构体类型与数组
23、类型有什么区别和联系?型与数组类型有什么区别和联系?湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院v一个结构变量只能表示一个实体的信息,如果一个结构变量只能表示一个实体的信息,如果有许多相同类型的实体,就需要使用有许多相同类型的实体,就需要使用结构数组结构数组。v结构数组是结构与数组的结合,与普通数组的结构数组是结构与数组的结合,与普通数组的不同之处在于不同之处在于每个数组元素都是一个结构类型每个数组元素都是一个结构类型的数据的数据,包括各个成员项。,包括各个成员项。9.2.3 9.2.3 结构数组结构数组 湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院1.1.结构体数组的
24、定义结构体数组的定义01Lilin808887.502Zhanghua92869903Wuli768078.5stu0stu1stu2结构数组的定义方法与结构变量相同结构数组的定义方法与结构变量相同单独定义:单独定义:先先定义结构体定义结构体类型类型,后后定义结构体定义结构体数组数组 struct node char id20;char name15;int score3;struct node stu30;直接定义:直接定义:在定义结构体类型同在定义结构体类型同时定义结构体数组时定义结构体数组 struct node char id20;char name15;int score3;stu
25、30;结构体类型名结构体类型名node可以不写可以不写湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院struct node char id20;char name15;int score3;;struct node student10=01,Wang li,78.5,98.5,86.5,02,Zhang Fun,88.5,78.5,81.5,03,Li Ling,76.5,68.5,76.5;2.2.结构体数组的初始化结构体数组的初始化结构体类型名结构体类型名 结构体数组名结构体数组名n初值表初值表1,初值表初值表2,.,初值表初值表n;思考:思考:v结构体数组初始化时,红色的括号能
26、去掉吗?结构体数组初始化时,红色的括号能去掉吗?v上面的例子中只给了前三个结构数组元素的初始化,对于其它元素,编上面的例子中只给了前三个结构数组元素的初始化,对于其它元素,编译器会预分配内存空间吗?译器会预分配内存空间吗?湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院3.3.结构数组元素成员的引用结构数组元素成员的引用 v结构数组元素的成员引用结构数组元素的成员引用结构体数组名下标.结构体成员名 v使用方法与同类型的变量完全相同使用方法与同类型的变量完全相同stu5.id=26;strcpy(stu5.name,Zhang San);stu6=stu5;湖南工业大学计算机与通信学院湖
27、南工业大学计算机与通信学院例例9-2 9-2 学生的基本信息包括学号、姓名、学生的基本信息包括学号、姓名、3 3门成绩、平均分、总分。输入门成绩、平均分、总分。输入三个学生的基本信息,计算总分和平均分,并按平均分从高分到低分输出三个学生的基本信息,计算总分和平均分,并按平均分从高分到低分输出for(i=0;i3;i+)float sum=0;printf(请输入学号:请输入学号:);gets(stu1i.id);printf(请输入姓名:请输入姓名:);gets(stu1i.name);for(j=0;jCLASS;j+)printf(请输入请输入%s 成绩成绩:,CLASSNAMEj);sc
28、anf(%f,&stu1i.scorej);getchar();/用来用来“吃掉吃掉”输入成绩后所输入的输入成绩后所输入的“回车回车”符符 sum+=stu1i.scorej;stu1i.sum=sum;stu1i.ave=stu1i.sum/3;分析分析 :排序需要内存中同时存在排序需要内存中同时存在3个学生的信息,个学生的信息,因此,此题考虑定义结构体数组存储所有因此,此题考虑定义结构体数组存储所有学生信息。存储所有学生信息后,用前面学生信息。存储所有学生信息后,用前面学习的选择法排序。学习的选择法排序。#include#define CLASS 3struct node char id1
29、0;/学号学号 char name15;/姓名姓名 float score3;/成绩成绩 float sum;/总分总分 float ave;/平均分平均分;char CLASSNAMECLASS30=计算机计算机,英语英语,数学数学;void main()struct node stu13,temp;int i,j;for(i=0;i2;i+)for(j=i+1;j3;j+)if(stu1j.ave=0;i-)printf(学号学号:%s姓名姓名:%s总成绩总成绩:%f平均成绩平均成绩%.2fn,stu1i.id,stu1i.name,stu1i.sum,stu1i.ave);for(j=0
30、;jx=0;/*指向运算符指向运算符*/n第二种更常用第二种更常用xypptpt结构指针:指向结构类型变量的指针结构指针:指向结构类型变量的指针湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院struct student int num;char name20;char sex;int age;;struct student stu3101,Lilin,M,18,102,Zhanghua,M,18,103,Wuli,F,19,;struct student *p=stu;main()for(;pnum,p-name,p-sex);说明:说明:v如果指针变量如果指针变量p p指向结构体数
31、指向结构体数组,则组,则p+1p+1指向结构体数组的下指向结构体数组的下一个元素,而不是当前元素的下一个元素,而不是当前元素的下一个成员。一个成员。v如果指针变量如果指针变量p p指向一个结构指向一个结构变量(或结构数组),就不能再变量(或结构数组),就不能再使之指向结构体变量(或结构数使之指向结构体变量(或结构数组元素)的某一成员组元素)的某一成员。p=stu;p=stu.name;(+p)-num (p+)-num numnamesexagestu0pstu1stu2p+1指向结构体数组的指针指向结构体数组的指针湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院思考题思考题9-39-
32、3:v指向结构体变量的指针定义后就可以直接使用吗?指向结构体变量的指针定义后就可以直接使用吗?v用结构指针的方法如何处理例用结构指针的方法如何处理例9-19-1和例和例9-29-2。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院用结构体类型数据作为函数参数有以下三种形式:用结构体类型数据作为函数参数有以下三种形式:v用结构体变量的用结构体变量的成员成员作参数作参数用法与普通变量作参数相同,值传递用法与普通变量作参数相同,值传递v用用结构体变量结构体变量作参数作参数函数的实参和形参必须都是结构体变量,程序效函数的实参和形参必须都是结构体变量,程序效率低,开销大,不主张用率低,开销大,不
33、主张用v用用结构体指针结构体指针或或结构体数组结构体数组作参数作参数提高运行效率,还可以修改结构体指针所指向的提高运行效率,还可以修改结构体指针所指向的结构体的内容结构体的内容9.2.5 9.2.5 结构变量、结构指针作为函数参数结构变量、结构指针作为函数参数湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院#include#define CLASS 3struct node char id10;/学号学号 char name15;/姓名姓名 float score3;/成绩成绩;char CLASSNAMECLASS30=计算机计算机,英语英语,数学数学;void main()stru
34、ct node stu13;int i,j;void outputinfo(struct node m);for(i=0;i3;i+)float sum=0;printf(请输入学号:请输入学号:);gets(stu1i.id);printf(请输入姓名:请输入姓名:);gets(stu1i.name);for(j=0;jCLASS;j+)printf(请输入请输入%s 成绩成绩:,CLASSNAMEj);scanf(%f,&stu1i.scorej);for(i=0;i3;i+)outputinfo(stu1i);结构变量作为函数参数结构变量作为函数参数 例例9-3 学生的基本信息包括学号、
35、姓学生的基本信息包括学号、姓名、名、3门成绩。输入门成绩。输入3个学生信息,并个学生信息,并输出显示。定义个输出功能的函数,输出显示。定义个输出功能的函数,要求用要求用结构体变量作函数参数。结构体变量作函数参数。void outputinfo(struct node m)printf(学号学号:%s姓名姓名:%s n,m.id,m.name);for(int j=0;jCLASS;j+)printf(%s 成绩成绩:%.2fn,CLASSNAMEj,m.scorej);传递结构时不使用“&”,所以实际上是传值调用,即,将结构变量的每个成员值逐个传送。湖南工业大学计算机与通信学院湖南工业大学计算
36、机与通信学院#include#define CLASS 3struct node char id10;/学号学号 char name15;/姓名姓名 float score3;/成绩成绩;char CLASSNAMECLASS30=计算机计算机,英英语语,数学数学;void main()struct node stu13;int i,j;void outputinfo(struct node m);for(i=0;i3;i+)float sum=0;printf(请输入学号:请输入学号:);gets(stu1i.id);printf(请输入姓名:请输入姓名:);gets(stu1i.name)
37、;for(j=0;jCLASS;j+)printf(请输入请输入%s 成绩成绩:,CLASSNAMEj);scanf(%f,&stu1i.scorej);outputinfo(&stu10);结构指针作为函数参数结构指针作为函数参数 例例9-4 改写例改写例9-3,学生的基本信息包括学生的基本信息包括学号、姓名、学号、姓名、3门成绩。输入门成绩。输入3个学生个学生信息,并输出显示。要求用结构体指信息,并输出显示。要求用结构体指针作函数参数,定义输出功能的函数。针作函数参数,定义输出功能的函数。void outputinfo(struct node*p)for(int i=0;iid,p-nam
38、e);for(int j=0;jscorej);用指针变量作函数参数进行传送时由实参传向形参的只是结构的地址。思考:v在例在例9-39-3中,主函数要调用中,主函数要调用outputinfo(structoutputinfo(struct node m)node m)函数三次输出函数三次输出3 3个结构数组元素,为什么在例个结构数组元素,为什么在例9-49-4中,主函中,主函数只需要调用数只需要调用outputinfo(structoutputinfo(struct node node*p)p)一次?一次?v例例9-49-4中实参为结构数组的首地址,与第七章向函数传中实参为结构数组的首地址,与
39、第七章向函数传 递数组的知识进行类比,递数组的知识进行类比,用形参用形参void void outputinfo(structoutputinfo(struct node stu1)node stu1)改写例改写例9-49-4。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院v 结构变量作为参数时,数据传递是结构变量作为参数时,数据传递是“值传递方式值传递方式”,如果结,如果结构参数包含的成员有很多,那么在参数的传递过程中就需要构参数包含的成员有很多,那么在参数的传递过程中就需要花费很多时间和空间。花费很多时间和空间。v 如果需要对主函数中定义的结构体数组成员赋值,即修改结如果需要对主
40、函数中定义的结构体数组成员赋值,即修改结构指针所指向的内容,根据前面所学知识,在这里也只能用构指针所指向的内容,根据前面所学知识,在这里也只能用传递地址的方式。传递地址的方式。v 结构指针作为函数参数,可以通过被调函数中结构指针的移结构指针作为函数参数,可以通过被调函数中结构指针的移动(如动(如p+p+)来完成对主函数中多个结构数组元素的操作;)来完成对主函数中多个结构数组元素的操作;而结构变量作为函数参数,只能完成对主函数中某一个结构而结构变量作为函数参数,只能完成对主函数中某一个结构数组元素的操作,要完成对多个结构数组元素的操作,需要数组元素的操作,要完成对多个结构数组元素的操作,需要在主
41、函数中循环调用以结构变量作为参数的函数。在主函数中循环调用以结构变量作为参数的函数。综上所述,用结构指针作为参数的效率更高,是更佳的选择。综上所述,用结构指针作为参数的效率更高,是更佳的选择。结构变量与结构指针作为函数参数的区别结构变量与结构指针作为函数参数的区别湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院v结构指针作为返回值的函数定义、调用方法与其结构指针作为返回值的函数定义、调用方法与其他函数一样他函数一样v如在学生系统中,对某学生信息的查询、对某学如在学生系统中,对某学生信息的查询、对某学生信息的修改、对某学生信息的删除,可以通过生信息的修改、对某学生信息的删除,可以通过函数
42、返回的结构指针值进行对这个学生定位。函数返回的结构指针值进行对这个学生定位。结构指针作为函数的返回值结构指针作为函数的返回值 湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院学以致用学以致用:你如何解决以下问题你如何解决以下问题?思考题思考题9-59-5:v编写程序自定义一函数,实现学生信息输入的编写程序自定义一函数,实现学生信息输入的功能,用结构指针作为函数参数的方法。功能,用结构指针作为函数参数的方法。v编写程序自定义一函数,实现计算平均分和总编写程序自定义一函数,实现计算平均分和总分的功能,用结构指针作为函数参数的方法。分的功能,用结构指针作为函数参数的方法。湖南工业大学计算机与
43、通信学院湖南工业大学计算机与通信学院9.2.6 9.2.6 链表链表v数组在内存中是顺序存储的,进行插入、删除操数组在内存中是顺序存储的,进行插入、删除操作时需要移动大量数据,程序的执行效率降低。作时需要移动大量数据,程序的执行效率降低。v在用数组存放数据时,一般需要事先定义好固定在用数组存放数据时,一般需要事先定义好固定长度的数组,如果事先不能确定最终人数,就要长度的数组,如果事先不能确定最终人数,就要定义数组足够大,以容纳下学生的数据,这样处定义数组足够大,以容纳下学生的数据,这样处理问题,缺乏灵活性,往往会浪费许多内存。理问题,缺乏灵活性,往往会浪费许多内存。前面我们学习了用结构体数组静
44、态地存储和处理学生前面我们学习了用结构体数组静态地存储和处理学生信息的方法,现在我们分析下这种方法的弊端。信息的方法,现在我们分析下这种方法的弊端。怎么解决呢?可以考虑逻辑上相邻的数据元素物理上可以随意存放,可以考虑逻辑上相邻的数据元素物理上可以随意存放,逻辑相邻元素用指针联系。按此设想,数据所占存储逻辑相邻元素用指针联系。按此设想,数据所占存储空间分为两个部分,一个部分存放结点值,一个部分空间分为两个部分,一个部分存放结点值,一个部分存放表示结点关系的指针。这样的结构即存放表示结点关系的指针。这样的结构即链表链表,链表链表是结构体的一种应用是结构体的一种应用。v这样,进行插入、删除操作时不需
45、要移动数据,只这样,进行插入、删除操作时不需要移动数据,只需要修改指针,程序效率提高。需要修改指针,程序效率提高。v链表是一种动态存储分配的数据结构,不需要预先链表是一种动态存储分配的数据结构,不需要预先占用足够大的内存空间。占用足够大的内存空间。湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院链表的概念链表的概念v一种一种动态存储动态存储分布的数据结构分布的数据结构v若干个同一结构类型的若干个同一结构类型的“结点结点”依次串接而成依次串接而成头指针头指针结点结点尾结点尾结点head9903 Qian 80 NULL9901 Wang 809902 Li 90湖南工业大学计算机与通信学
46、院湖南工业大学计算机与通信学院链表的概念结点定义链表的概念结点定义structstruct stud_nodestud_node intint num;num;char name20;char name20;intint score;score;structstruct stud_nodestud_node *next;next;结构的递归定义结构的递归定义head9905 Qian 80 NULL9901 Wang 809902 Li 90湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院各域值各域值1.实际单元地址实际单元地址2.空值,即为空值,即为3.无值或随机值无值或随机值str
47、uct student stu1,stu2;stu1link=&stu2;stu2link=NULL;headstu1stu2链表与空指针链表与空指针湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院1.1.在链表中易于插入一个新节点。在链表中易于插入一个新节点。各域值各域值各域值head各域值2.2.在链表中易于删除一个节点。在链表中易于删除一个节点。各域值各域值各域值head3.3.在链表中不易于检索一个节点。在链表中不易于检索一个节点。4.4.在链表中易于出现断链。在链表中易于出现断链。链表的操作原理链表的操作原理湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院struct
48、 student char name20;long num;struct student *link;*rp,*lp,*p;各域值各域值p=(struct student *)malloc(sizeof(student);strcpy(pname,zhang san);pnum=9901012;plink=null;rplink=p;rp=p;各域值各域值链表的建立链表的建立(尾部插入新结点)尾部插入新结点)湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院各域值各域值各域值p=lp;lp=lplink;free(p);注意注意删除节点就是将该节点从链表中分离出来。删除节点就是将该节点从
49、链表中分离出来。删除删除后,一定将该节点归还给系统,后,一定将该节点归还给系统,以便于再分配;以便于再分配;否则,链表将永久丢失。否则,链表将永久丢失。链表的删除链表的删除(前端删除)前端删除)int delete_front(struct link*head)struct link*p;if(*head=NULL)return(0);else p=*head;*head=(*head).next;free(p);return(1);湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院各域值各域值各域值nullint delete_rear(struct link*head)struct
50、link*p;if(*head)=NULL)return(0);else if(*head).next=null)free(*head);*head=null else p=*head;while(p.next.next!=null)p=p.next;free(p.next);p.next=null;return(1);链表的删除链表的删除(后端删除)后端删除)湖南工业大学计算机与通信学院湖南工业大学计算机与通信学院各域值各域值各域值int delete_mid(struct link*head,int x)struct link*p,*q;if(*head=NULL)return(0);el