




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C语言程序设计进阶篇C语言程序设计提高篇第第1111章结构体、共同体和枚举类型章结构体、共同体和枚举类型 C语言程序设计进阶篇结构体类型定义结构体类型定义结构体变量定义引用结构体变量定义引用结构体数组与指针结构体数组与指针结构体与函数结构体与函数结构体数组应用结构体数组应用结构体与链表应用结构体与链表应用C语言程序设计进阶篇认识引入结构体类型的必要性认识引入结构体类型的必要性, ,描述结构体类型变描述结构体类型变量的定义方法量的定义方法, ,正确地引用结构体变量正确地引用结构体变量, ,正确的对正确的对结构体变量初始化。结构体变量初始化。牢记结构体数组的定义,并能正确地使用。牢记结构体数组的定
2、义,并能正确地使用。牢记指向结构体类型数据的定义牢记指向结构体类型数据的定义, ,并能正确地使用。并能正确地使用。使用结构体指针处理链表的各种操作。使用结构体指针处理链表的各种操作。使用使用typedeftypedef定义新类型名来代替已有类型名。定义新类型名来代替已有类型名。C语言程序设计进阶篇11.1 11.1 结构体类型结构体类型11.1.1 11.1.1 结构体类型的认识结构体类型的认识实体:实体:指客观世界的人、事、物、概念等。指客观世界的人、事、物、概念等。属性:属性:实体的特征,用以描述实体。实体的特征,用以描述实体。学生是个实体,可以通过以下属性给以描述。学生是个实体,可以通过
3、以下属性给以描述。实体NameScoreAgeSexNumAddr实实体体:属属性性:C语言程序设计进阶篇上海上海57857887.6.1387.6.13女女赵六赵六060411136060411136山东山东5505502.1男男王五王五060411135060411135浙江浙江56256286.11.2586.11.25女女李四李四060411102060411102江苏江苏58458487.4.1987.4.19男男张三张三060411101060411101生生 源源成成 绩绩出生日期出生日期性性 别别姓姓 名名学学 号号 这是一个二维表,但却无法用二维数组来描
4、述它,这是一个二维表,但却无法用二维数组来描述它,原因是用来描述学生信息的五项数据类型各不相同。原因是用来描述学生信息的五项数据类型各不相同。能否能否将一个学生的信息作为一个完整的类型存放呢?将一个学生的信息作为一个完整的类型存放呢?为了能方为了能方便地处理此类问题,在便地处理此类问题,在C C语言中,规定了一种新的数据类语言中,规定了一种新的数据类型型“结构体类型结构体类型”,可有效地表示类型互异又逻辑相关的,可有效地表示类型互异又逻辑相关的数据实体。数据实体。C语言程序设计进阶篇11.1.2 11.1.2 结构体类型的定义结构体类型的定义“结构体类型结构体类型”是一种构造类型,它是由若干是
5、一种构造类型,它是由若干“成员成员”组成的,它可以将若干个不同数据类型的变量组合在一起。组成的,它可以将若干个不同数据类型的变量组合在一起。结构体类型的声明形式为:结构体类型的声明形式为:struct struct 结构体类型名称结构体类型名称 成员列表成员列表; ; ;其中,其中,structstruct是关键字,是关键字,结构体类型名称结构体类型名称为用户自定义为用户自定义标志符,各标志符,各成员定义语句成员定义语句放在花括号中构成复合语句,放在花括号中构成复合语句,花括号后面的花括号后面的分号分号是整个定义语句的结尾。是整个定义语句的结尾。C语言程序设计进阶篇下面是用于描述日期的结构体类
6、型的声明:下面是用于描述日期的结构体类型的声明: struct date int year; int month; int day; ;由于由于datedate结构体的三个成员具有相同的类型结构体的三个成员具有相同的类型intint,它,它也可以改为如下形式:也可以改为如下形式: struct date int year,month,day; ;C语言程序设计进阶篇“学生信息学生信息” 的结构体类型可以这样声明:的结构体类型可以这样声明:struct student int num ; char name20; char sex; struct date birthday; float sco
7、re; char place10; ;注意,学生信息结构体中加入类型为注意,学生信息结构体中加入类型为struct struct datedate的的birthdaybirthday数据项,构成数据项,构成结构体的嵌套定义结构体的嵌套定义。C语言程序设计进阶篇结构体类型的几点说明:结构体类型的几点说明:(1 1)关键字)关键字structstruct是用来声明结构体类型的,不能省略。是用来声明结构体类型的,不能省略。(2 2)C C语言中的结构体类型可以嵌套定义,即结构体的成语言中的结构体类型可以嵌套定义,即结构体的成员允许又是结构体。员允许又是结构体。(3 3)成员表列不可为空,至少要有一个
8、成员。)成员表列不可为空,至少要有一个成员。(4 4)不表示复合语句,其后有分号。不表示复合语句,其后有分号。(5 5)同一结构体的成员不能重名;而不同结构体的成员可)同一结构体的成员不能重名;而不同结构体的成员可以重名,结构体成员和其他变量可以重名,结构体类型以重名,结构体成员和其他变量可以重名,结构体类型与其成员或其他变量可以重名。与其成员或其他变量可以重名。(6 6)一般把结构体类型声明放到文件最前面,也可以放在)一般把结构体类型声明放到文件最前面,也可以放在头文件里,若在函数内部声明结构体类型,则该函数之头文件里,若在函数内部声明结构体类型,则该函数之外无法引用此结构体类型。外无法引用
9、此结构体类型。C语言程序设计进阶篇11.2 11.2 结构体变量结构体变量类型定义只是说明了一个实体相应的属性描述,类型定义只是说明了一个实体相应的属性描述,只有通过定义相应的变量,并赋于一定的值才能构成只有通过定义相应的变量,并赋于一定的值才能构成实体的元素实体的元素( (记录记录) )。11.2.1 11.2.1 结构体变量的定义结构体变量的定义(1 1)先定义结构体类型,再定义结构体变量。)先定义结构体类型,再定义结构体变量。 例如例如: : 假设已定义结构体类型假设已定义结构体类型struct studentstruct student,即可用它来,即可用它来定义变量。定义变量。 st
10、ruct student stu1;C语言程序设计进阶篇(2 2)在定义结构体类型的同时,定义结构体变量。)在定义结构体类型的同时,定义结构体变量。struct student int num ; char name20; char sex; struct data birthday; float score; char place10; stu1,stu2; C语言程序设计进阶篇(3 3)直接定义结构体类型变量。)直接定义结构体类型变量。struct int num ; char name20; char sex; struct data birthday; float score; cha
11、r place10; stu1,stu2;C语言程序设计进阶篇注意:注意:正确区分类型与变量的概念,只能对正确区分类型与变量的概念,只能对变量赋值、存取或运算,不能对一个类型变量赋值、存取或运算,不能对一个类型赋值、存取或运算;赋值、存取或运算; C语言程序设计进阶篇11.2.2 11.2.2 结构体变量的存储模式结构体变量的存储模式结构体变量的各个成员分量在内存中占用连续存储区结构体变量的各个成员分量在内存中占用连续存储区域,域,各成员分量占用内存的长度之和即为结构体变量占用内各成员分量占用内存的长度之和即为结构体变量占用内存的大小。存的大小。 struct studentstruct st
12、udent类型的结构体变量类型的结构体变量stu1stu1的内存分配模的内存分配模式如图所示。式如图所示。 yearmonthbirthdaydaynumnamesexbirthdayscoreplacestu14 4字节字节2020字节字节1 1字节字节1212字节字节4 4字节字节1010字节字节C语言程序设计进阶篇11.2.3 11.2.3 结构体变量的引用结构体变量的引用结构体是由若干成员构成的聚合体。在对结构体变结构体是由若干成员构成的聚合体。在对结构体变量操作时,常常需要对其中的每个成员施加某种特定的量操作时,常常需要对其中的每个成员施加某种特定的操作。操作。引用形式:引用形式:
13、结构体变量名结构体变量名. .成员名成员名例如:例如:stud.score stud.birthday.year stud.birthday.month stud.birthday.dayC语言程序设计进阶篇11.2.4 11.2.4 结构体变量的基本操作结构体变量的基本操作(1 1)初始化赋值。)初始化赋值。 一般形式:一般形式: struct struct 结构类型名结构类型名 结构变量结构变量 初值表初值表; ; 例如:例如: struct student int num ; char name20; char sex; struct data birthday; f
14、loat score; char place10; stud=1001,Zhangsan,M,1986,4,19,90,Suzhou; C语言程序设计进阶篇(2 2)结构体变量的输入)结构体变量的输入/ /输出。输出。一般情况下,结构体变量不能整体引用,只能引用其一般情况下,结构体变量不能整体引用,只能引用其成员变量。因此,在输入(输出)结构体变量的时候,需要成员变量。因此,在输入(输出)结构体变量的时候,需要分别输入(输出)每个成员的内容,以此达到输入(输出)分别输入(输出)每个成员的内容,以此达到输入(输出)结构体变量全部内容的目的。结构体变量全部内容的目的。例如:例如: 输入输入stu1
15、stu1的学号、姓名、成绩可写为:的学号、姓名、成绩可写为: scanf(“%d%s%f”,&stu1.num,,&stu1.score); 输出输出stu1stu1的学号、姓名、成绩可写为:的学号、姓名、成绩可写为: printf(“%d%s%f”, stu1.num,, stu1.score);C语言程序设计进阶篇【例【例11.111.1】键盘输入学生】键盘输入学生“张三张三”的信息,然后输出显示。的信息,然后输出显示。#include void main() struct date int year; int month; int day; ; str
16、uct int num ; char name20; char sex; struct date birthday; float score; char place10; stud=1001,Zhangsan,M,1986,4,19,90,Suzhou; printf (%d,%s,%c,stud.num,,stud.sex); printf(%d/%d/%d,stud.birthday.year,stud.birthday.month,stud.birthday.day); printf(%.1f,%sn,stud.score,stud.place);C语言程序设计进阶篇(
17、3 3)结构体变量的赋值)结构体变量的赋值在在C C语言中,提供了两种方式为结构体变量赋值:语言中,提供了两种方式为结构体变量赋值:一种是对每个成员分别进行赋值;另一种是整体赋值。一种是对每个成员分别进行赋值;另一种是整体赋值。 对成员分别赋值:对成员分别赋值:stud.num=1001; strcpy(, Zhangsan); stud.sex=M; stud.birthday.year=2000; stud.birthday.month=12; stud.birthday.day=01; stud.score=80.5; strcpy(stud.place, buildi
18、ng1);C语言程序设计进阶篇假设有定义:假设有定义: struct stdent stud1 对结构变量整体赋值:对结构变量整体赋值: stud1=stud; 结构体变量之间的相互赋值,实质上是两个结结构体变量之间的相互赋值,实质上是两个结构体变量相应的存储空间中的所有数据直接复制,构体变量相应的存储空间中的所有数据直接复制,包括复杂类型在内的所有结构体成员都被直接赋值,包括复杂类型在内的所有结构体成员都被直接赋值,如字符串、结构体类型等。如字符串、结构体类型等。C语言程序设计进阶篇11.3 11.3 结构体数组结构体数组11.3.1 11.3.1 结构体数组的定义和引用结构体数组的定义和引
19、用 与定义结构体变量的方法一样,在结构体变量名之与定义结构体变量的方法一样,在结构体变量名之后指定元素个数,就能定义结构体数组。后指定元素个数,就能定义结构体数组。 例如:例如: struct student int num; char name20; float score; stud30; C语言程序设计进阶篇则该数组共有则该数组共有3030个元素,分别是个元素,分别是stud0stud0、stud29stud29,数组元素各成员的引用形式为:数组元素各成员的引用形式为: stud0.num、、stud0.score; stud1.num、、stud
20、1.score; stud29.num、、stud29.score;C语言程序设计进阶篇11.3.2 11.3.2 结构体数组的初始化结构体数组的初始化既然结构体变量可以初始化,结构体数组当然可以作既然结构体变量可以初始化,结构体数组当然可以作初始化赋值。例如:初始化赋值。例如:struct student int num; char name20; float score;stud3=1001,ZhangSan,93,1002,LiSi,90.5,1003,WangWu,85;C语言程序设计进阶篇【例【例11.211.2】设某组有】设某组有4 4个人,填写表个人,填写表
21、11.311.3所示的成绩登所示的成绩登记表,编程实现对表格的计算,求解出每个人的三科记表,编程实现对表格的计算,求解出每个人的三科平均成绩,并按平均成绩由高分到低分排出名次。平均成绩,并按平均成绩由高分到低分排出名次。C语言程序设计进阶篇(1 1)结构体类型数组的输入。)结构体类型数组的输入。(2 2)求解各学生的三科平均成绩。)求解各学生的三科平均成绩。(3 3)按学生的平均成绩排序。)按学生的平均成绩排序。(4 4)按名次输出学生成绩信息。)按名次输出学生成绩信息。(5 5)定义)定义main()main()函数,调用各函数模块。函数,调用各函数模块。我们把问题分解为如下子问题,通过我们
22、把问题分解为如下子问题,通过函数函数来实现。来实现。C语言程序设计进阶篇#include #include #define STUDENT struct studentSTUDENT int num; char name20; float score3; float average;void main() void input(STUDENT*,int); / /* *函数声明函数声明* */ / void aver(STUDENT*,int); void sort(STUDENT*,int); void output(STUDENT*,int); STUDENT stud4; / /* *
23、定义结构体数组定义结构体数组* */ / input(stud,4); / /* *依次调用自定义函数依次调用自定义函数* */ / aver(stud,4); sort(stud,4); output(stud,4); C语言程序设计进阶篇void input(STUDENT arr,int n)/ /* * 输入输入n n名学生的信息名学生的信息 * */ / int i,j; printf(nInput Name,Math,Chinese,English:n); for(i=0;in;i+) arri.num=i+1; scanf(%s,); for(j=0;j3;j+
24、) scanf(%f,&arri.scorej); C语言程序设计进阶篇void aver(STUDENT *arr,int n)/ /* * 求解各学生的三科平均成绩求解各学生的三科平均成绩 * */ / int i,j; float sum; for(i=0;in;i+) sum=0; for(j=0;j3;j+) sum=sum+arri.scorej; arri.average=sum/3; C语言程序设计进阶篇void sort(STUDENT *arr,int n)/ /* * 按学生的平均成绩排序按学生的平均成绩排序 * */ / struct student temp; int
25、 i,j; for(i=0;in-1;i+) for(j=0;jarrj+1.average) temp=arrj; arrj=arrj+1; arrj+1=temp; C语言程序设计进阶篇void output(STUDENT arr,int n)/ /* * 按名次输出学生成绩信息按名次输出学生成绩信息 * */ / int i,j; printf( Number Name Math Chinese English Averagen); for(i=0;in;i+) printf(%8d%8s, arri.num,); for(j=0;j-结构体成员名结构体成员名 例如:
26、例如: p-num p-name p-score (2 2)( (* *指针变量指针变量) )结构体成员名结构体成员名 例如:例如: (*p).num (*p).name (*p).score 一般习惯使用运算符一般习惯使用运算符“-”来标记。来标记。C语言程序设计进阶篇课堂练习:课堂练习:请指出下列程序的错误所在:请指出下列程序的错误所在: struct person char name20; int count; x1=ZhongHua, 10; void main( ) int *p;p=&x1;printf (%sn%dn, (*p).name, (*p).count)错误的原因:错误
27、的原因:p p不是结构指针变量不是结构指针变量可改为可改为:struct person *pC语言程序设计进阶篇【例【例11.311.3】通过结构体指针输出结构体数组。】通过结构体指针输出结构体数组。#include stdio.h struct date int year; int month; int day; ; struct student int num ; char name20; char sex; struct date birthday; ;struct student stud4=1001,ZhangSan,M,1986,4,19, 1002,LiSi,F,1987,9,2
28、5, 1003,WangWu,M,1986,12,1, 1004,ZhaoLiu,F,1987,5,16;C语言程序设计进阶篇void main() struct student *p; printf( No Name Sex Birthday n); for(p=stud;pnum); printf(%10s ,p-name); printf(%4c ,p-sex); printf(%8d-%2d-%2dn,p-birthday.year, p- birthday.month,p-birthday.day); C语言程序设计进阶篇11.4.3 11.4.3 结构体指针作函数参数结构体指针作函
29、数参数结构体变量作函数参数:结构体变量作函数参数: 进行整体传送。这种传送要将结构体变量的全部进行整体传送。这种传送要将结构体变量的全部成员逐个传送,时间和空间开销很大,效率低。成员逐个传送,时间和空间开销很大,效率低。指针变量作函数参数:指针变量作函数参数: 由实参传向形参的只是结构体变量的地址,从而由实参传向形参的只是结构体变量的地址,从而减少了时间和空间的开销。减少了时间和空间的开销。C语言程序设计进阶篇【例【例11.411.4】用函数调用方式,改写例】用函数调用方式,改写例11.311.3,编写一个,编写一个专门的显示函数专门的显示函数display()display()来输出结构体数
30、组的内容,来输出结构体数组的内容,通过主函数调用来实现显示。通过主函数调用来实现显示。#include stdio.hstruct student int num; char name20; float score;stud=1001,ZhangSan,93, 1002,LiSi,90.5, 1003,WangWu,85, 1004,ZhaoLiu,95;C语言程序设计进阶篇void main() void display(struct student *); int i; printf( No Name scoren); for(i=0;inum,p-name,p-score); C语言程序
31、设计进阶篇11.5 11.5 链表链表静态数据结构静态数据结构:前面讨论的各种基本类型和组合类型的前面讨论的各种基本类型和组合类型的数据都属静态数据结构,它们所占存储空间的大小在程数据都属静态数据结构,它们所占存储空间的大小在程序的说明部分就已经确定,如变量、数组、结构等,它序的说明部分就已经确定,如变量、数组、结构等,它们不能在程序运行过程中加以改变。们不能在程序运行过程中加以改变。动态数据结构动态数据结构:它是在程序运行过程中动态的建立起来它是在程序运行过程中动态的建立起来的,这种数据结构的规模大小在程序执行期间可动态的的,这种数据结构的规模大小在程序执行期间可动态的变化。变化。 动态数据
32、结构中最基本的形式是链表和二叉树,它动态数据结构中最基本的形式是链表和二叉树,它们在应用软件和系统软件的设计中非常有用。们在应用软件和系统软件的设计中非常有用。C语言程序设计进阶篇headhead: : 称为表头,仅存放一个地址,无数据。称为表头,仅存放一个地址,无数据。head数据数据D DNull数据数据C数据数据B B数据数据A A数据数据指针指针: 为数据块,又称为链表的结点为数据块,又称为链表的结点( (nodenode) ),由两部分由两部分 组成,数据和指针。组成,数据和指针。数据数据:该结点的具体数据:该结点的具体数据指针指针:下一个结点的地址:下一个结点的地址11.5.1 1
33、1.5.1 链表概述链表概述C语言程序设计进阶篇链表结点的数据结构可描述为链表结点的数据结构可描述为struct struct 结构名结构名 数据成员列表数据成员列表; ; struct struct 结构名结构名 * *指针名指针名; ;例如例如: :struct node int num; struct node *next;numnextC语言程序设计进阶篇11.5.2 11.5.2 链表的基本操作链表的基本操作1 1创建链表创建链表 创建链表是指从无到有地建立起一个链表创建链表是指从无到有地建立起一个链表 。NULL(a a)表头插入法)表头插入法headpNULLheadp(b b)
34、表尾插入法)表尾插入法lastC语言程序设计进阶篇【例【例11.511.5】写一函数建立一个有若干名学生数据的单】写一函数建立一个有若干名学生数据的单向链表,当输入的成绩为向链表,当输入的成绩为 1 1时结束输入。时结束输入。结点的数据结构可定义为:结点的数据结构可定义为:struct node int num; int score; struct node *next; ;用宏定义结点的长度:用宏定义结点的长度:#define LEN sizeof(struct node)C语言程序设计进阶篇单链表的创建过程(表头插入法):单链表的创建过程(表头插入法):(1 1)创建一个空表。)创建一个空
35、表。 head=NULL;(2 2)利用)利用malloc()malloc()函数向系统申请分配一个结点。函数向系统申请分配一个结点。 p=(struct node*)malloc(sizeof(struct node);(3 3)表头插入操作。)表头插入操作。 p-next=head; head=p;(4 4)若有后续结点要接入链表,转()若有后续结点要接入链表,转(2 2),否则结束。),否则结束。C语言程序设计进阶篇struct node *create( ) / /* *创建一个链表并返回一个指向链表头结点的指针创建一个链表并返回一个指向链表头结点的指针* */ / struct no
36、de *head,*p; head=NULL; p=(struct node*)malloc(LEN); / /* *创建第一个结点创建第一个结点* */ / scanf(%d%d,&p-num,&p-score); while(p-score!=-1)/ /* *若输入成绩不为若输入成绩不为-1-1,插入,插入* */ / p-next=head; head=p; p=(struct node*)malloc(LEN); / /* *开辟下一个结点开辟下一个结点* */ / scanf(%d%d,&p-num,&p-score); ; free(p); / /* *释放成绩为释放成绩为-1-
37、1的结点所占的内存的结点所占的内存* */ / return(head); / /* *链表创建完毕,返回头指针链表创建完毕,返回头指针* */ /C语言程序设计进阶篇2 2插入结点插入结点可以在表头、表中或表尾插入结点。下面给出了可以在表头、表中或表尾插入结点。下面给出了在键表中插入结点的示意图。在键表中插入结点的示意图。headp0pNULLp1C语言程序设计进阶篇【例【例11.611.6】以例】以例11.511.5建立的链表为例。假设链表中的结建立的链表为例。假设链表中的结点已按学号从小到大排序,编写函数,在单链表中插入点已按学号从小到大排序,编写函数,在单链表中插入结点结点p p,使链
38、表仍然有序。,使链表仍然有序。在链表中插入结点时应考虑插入位置在头结点之前还是在表在链表中插入结点时应考虑插入位置在头结点之前还是在表的中间,另外还要考虑空表的情况。具体算法描述如下:的中间,另外还要考虑空表的情况。具体算法描述如下:(1 1)若链表空,则插入结点即为头结点。)若链表空,则插入结点即为头结点。 head=p; p-next=NULL;(2 2)若插入位置在头结点之前,则执行下列语句。)若插入位置在头结点之前,则执行下列语句。 p-next=head; head=p;(3 3)否则,从链表头开始逐一查找要插入位置的前一个结点,)否则,从链表头开始逐一查找要插入位置的前一个结点,并
39、保存为并保存为p0p0,然后将结点,然后将结点p p插入到插入到p0p0之后。之后。 p-next=p1; p0-next=p;C语言程序设计进阶篇struct node *insert(struct node *head,struct node *p)/ /* *向以向以headhead为头结点的有序链表中插入结点为头结点的有序链表中插入结点p p,插入后链表仍有序,插入后链表仍有序* */ / struct node *p0,*p1; if(head=NULL) / /* * 若链表空,则插入结点即为头结点若链表空,则插入结点即为头结点 * */ / head=p; p-next=NULL
40、; return(head); if(p-numnum) / /* * 欲插入的结点欲插入的结点p p的学号最小,将的学号最小,将p p插入到头结点之前插入到头结点之前 * */ / p-next=head; head=p; return(head); C语言程序设计进阶篇p1=head; while(p-nump1-num)&(p1-next!=NULL) / /* *查找合适的位置查找合适的位置* */ / p0=p1; p1=p1-next; if(p-numnum) / /* * 在链表的中间找到合适位置,插入结点在链表的中间找到合适位置,插入结点 * */ / p-next=p1;
41、p0-next=p; else / /* *欲插入的结点欲插入的结点p p的学号最大,将的学号最大,将p p插入到尾结之后插入到尾结之后* */ / p1-next=p; p-next=NULL; return(head);C语言程序设计进阶篇实际上,可以通过调用实际上,可以通过调用insert()insert()函数实现一个有序链表的创建。函数实现一个有序链表的创建。struct node *create( ) / /* *创建一个链表并返回一个指向链表头结点的指针创建一个链表并返回一个指向链表头结点的指针* */ / struct node *head,*p; head=NULL; p=(
42、struct node*)malloc(LEN); / /* *创建第一个结点创建第一个结点* */ / scanf(%d%d,&p-num,&p-score); while(p-score!=-1) / /* *若输入成绩不为若输入成绩不为 1 1,则进入循环执行插入操作,则进入循环执行插入操作* */ / head=insert(head,p); p=(struct node*)malloc(LEN); / /* *开辟下一个结点开辟下一个结点* */ / scanf(%d%d,&p-num,&p-score); ; free(p); / /* *释放学号为释放学号为0 0的结点所占的内存
43、的结点所占的内存* */ / return(head); / /* *链表创建完毕,返回头指针链表创建完毕,返回头指针* */ /C语言程序设计进阶篇3 3删除结点删除结点从一个链表中删去一个结点,只要改变链接从一个链表中删去一个结点,只要改变链接关系即可,即修改结点指针成员的值。关系即可,即修改结点指针成员的值。 headpNULL(a a)删除表头结点)删除表头结点headpNULLpre(b b)删除表中间结点)删除表中间结点C语言程序设计进阶篇【例【例11.711.7】以例】以例11.511.5建立的学生链表为例,编写函数建立的学生链表为例,编写函数删除单链表中的学号为删除单链表中的学
44、号为numnum的结点的结点p p。删除结点时应判断结点在链表中的位置,具体算法描述如下:删除结点时应判断结点在链表中的位置,具体算法描述如下:(1 1)若)若p p为头结点,第二个结点成为新的头结点并转(为头结点,第二个结点成为新的头结点并转(4 4),),否则执行(否则执行(2 2)。)。 head=head-next;(2 2)寻找要删除结点)寻找要删除结点p p,注意保存要删结点的前一个结点,注意保存要删结点的前一个结点prepre。 pre=head; while(pre-next!=p)&(pre-next!=NULL) pre=pre-next;C语言程序设计进阶篇(3 3)找到
45、要删除结点则修改链接关系。)找到要删除结点则修改链接关系。 条件(条件(2 2)中,若)中,若whilewhile循环中条件循环中条件pre-next=NULLpre-next=NULL成成立说明链表中不存在结点立说明链表中不存在结点p p;若条件;若条件pre-next=ppre-next=p成立,成立,则找到结点则找到结点p p,执行语句,执行语句“pre-next=pre-next-next;”,将它删除。将它删除。(4 4)释放删除结点的内存,函数结束。)释放删除结点的内存,函数结束。 free(p);C语言程序设计进阶篇struct node *delete(struct node
46、*head,int num) / /* * 删除单链表中的学号为删除单链表中的学号为numnum的结点的结点p p,函数返回删除结点,函数返回删除结点p p后的单链表头结点后的单链表头结点* */ / struct node *pre,*p; if(head=NULL) / /* *链表为空链表为空* */ / printf(nlist is empty!n); return NULL; if(head-num=num) / /* *要删除结点为头结点要删除结点为头结点* */ / p=head; head=head-next; C语言程序设计进阶篇else pre=head; p=pre-n
47、ext; / /* *从头结点开始查找从头结点开始查找* */ / while(p!=NULL & p-num!=num) pre=p; p=p-next; if(p-num=num) / /* * 找到了需删除的结点找到了需删除的结点 * */ / pre-next=p-next; / /* * 后继结点的地址赋予前一结点后继结点的地址赋予前一结点 * */ / free(p); / /* * 释放结点所占的内存释放结点所占的内存 * */ / return(head);C语言程序设计进阶篇4 4输出链表的值输出链表的值【例【例11.811.8】以例】以例11.511.5建立的学生链表为例,
48、编写输出链表的建立的学生链表为例,编写输出链表的函数。函数。void print(struct node *head) / /* * 遍历链表,从表头开始,依次输出每个结点的值遍历链表,从表头开始,依次输出每个结点的值 * */ / struct node *p; printf(These records are:n); p=head; if(head!=NULL) do printf(%d%5dn,p-num,p-score); / /* *输出结点的值输出结点的值* */ / p=p-next; / /* * 指针指针p p后移,指向下一个结点后移,指向下一个结点 * */ / while
49、(p!=NULL);C语言程序设计进阶篇11.5.3 11.5.3 链表综合应用举例链表综合应用举例【例【例11.911.9】用链表管理学生成绩信息。】用链表管理学生成绩信息。mainmain函数依次调用函数依次调用creatcreat函数,创建按学号排序的有序单链表;调用函数,创建按学号排序的有序单链表;调用insertinsert函函数将一个学生的信息(学号、成绩)插入到链表中,使链数将一个学生的信息(学号、成绩)插入到链表中,使链表仍然有序;调用表仍然有序;调用deletedelete函数将指定学号的结点从链表中函数将指定学号的结点从链表中删除;要求每次调用完上述函数之后,都要调用删除;
50、要求每次调用完上述函数之后,都要调用printprint函数函数输出链表当前结点的内容。输出链表当前结点的内容。C语言程序设计进阶篇程序阅读程序阅读: :设设headhead是是nodenode类型的全程量,以类型的全程量,以headhead为头指为头指针的链表各节点的值如下图所示。针的链表各节点的值如下图所示。 head 3 ()4 ()5 ()6 ()7 NULL head 3 ()4 ()5 ()6 ()7 NULL 调用调用funfun(headhead)返回值是)返回值是 。#include#define LEN sizeof(struct node) struct node int
51、 num; struct node *next; ;练练 习习C语言程序设计进阶篇int fun(struct node*h) int k=0;struct node*p=h; while(p!=NULL) if(p-next!=NULL)k+=p-num; p=p-next; return k; void main() struct node*head ,*p1,*p2; int i; head=(struct node *) malloc(LEN);p1=head; for(i=3;inext=p2; p2-num=i;p2-next=NULL; p1=p2;printf(“%dn”,fu
52、n(head-next); 0371218 练练 习习C语言程序设计进阶篇程序填空程序填空: :已建立学生已建立学生 英语英语 课程的成绩链表(成绩存于课程的成绩链表(成绩存于scorescore域域中,学号存于中,学号存于num num 域中),下列函数用于查询某个学生的成绩并域中),下列函数用于查询某个学生的成绩并输出。输出。void require (head,no)struct student *head; int no; struct student * p; if( ) p = head; while(p-next!=NULL & no!=(*p).num) _; if( )pri
53、ntf (%6.1fn,p-num); else printf (%ld not been found!n,no); head!=NULLp=p-next no=p.num 练练 习习C语言程序设计进阶篇程序填空程序填空: :下列函数用于在节点类型为下列函数用于在节点类型为ltabltab的非空链表中插入一的非空链表中插入一个节点(由形参指针变量个节点(由形参指针变量p0p0指向),链表按照节点数据成员指向),链表按照节点数据成员nono的的升序排列,填空将程序补充完整。升序排列,填空将程序补充完整。ltab *insert(ltab *head, ltab *stud) ltab *p0,
54、*p1, *p2; p1=head; p0=stud; while(p0-nop1-no)&((1)) p2=p1; p1=p1-next; if(p0-nono) if(head=p1) p0-next=head; head=p0; else p2-next=p0; (2) else p1-next=p0; (3) return (head);(1)(1) p1 - next != NULL p1 - next != NULL(2)(2) p0 - next = p1; p0 - next = p1; (3)(3) p0 - next = NULL; p0 - next = NULL;练练
55、习习C语言程序设计进阶篇程序阅读程序阅读# includevoid main() struct info int data; struct info *pn; struct info base, p; base=NULL; for(int i=0; idata=i+1; p-pn=base; base=p; p=base; while(p!=NULL) printf(%2d, p-data); p=p-pn; printf(n);10 9 8 7 6 5 4 3 2 1 练练 习习C语言程序设计进阶篇 1-5 7练练 习习程序阅读程序阅读#includevoid main( ) struct
56、node int x; struct node *next; *p1,*p2=NULL; int a5=7,6,-5,28,1,i,j,s; for(i=0;i5;i+) s=0; for(j=1;jx=ai;p1-next=p2;p2=p1; while(p1!=NULL) printf(“%dn”,p1-x);p1=p1-next ;C语言程序设计进阶篇11.6 11.6 共用体共用体11.6.1 11.6.1 共用体的概念共用体的概念 所谓共用体类型是指将不同的数据项组织成一个整体,所谓共用体类型是指将不同的数据项组织成一个整体,它们在内存中占用同一段存储单元。其定义方式与结构体类它们在
57、内存中占用同一段存储单元。其定义方式与结构体类型完全相同。把结构体类型中的型完全相同。把结构体类型中的关键字关键字structstruct换成换成unionunion即即可可。 例如例如: :union data char ch; int i; float f; un1,un2;C语言程序设计进阶篇与结构体类似之处:与结构体类似之处:由不同的数据项组成一个整体。由不同的数据项组成一个整体。与结构体不同之处:与结构体不同之处:占用的内存单元不同。占用的内存单元不同。结构体结构体struct data char ch; int i; float f; ;chchi if f1 14 44 49 9
58、共用体共用体struct data char ch; int i; float f; ;chchi if f4 4字节字节字节字节C语言程序设计进阶篇一个共用体中可能有若干个不同类型的成员,但在任一个共用体中可能有若干个不同类型的成员,但在任何时刻,只有一个成员的值被存储。这就是最后赋给它何时刻,只有一个成员的值被存储。这就是最后赋给它的值。的值。#includeunion data char ch; int i; float f;void main( )union data un; un.ch=d; un.i=40; un.f=12.6;printf(%5c%5d%5.1fn,un.ch,u
59、n.i,un.f); 运行结果:运行结果:?109534249012.6输出结果中,除了输出结果中,除了un.fun.f的值外,的值外,un.chun.ch和和un.iun.i的值是我们无法预料的的值是我们无法预料的 C语言程序设计进阶篇共用体类型可以出现在结构体类型定义中,反之亦然。共用体类型可以出现在结构体类型定义中,反之亦然。例如:例如: union ub char s40; int x; ; struct st int a; char c; union ub x1; ; union un int i; struct st s1; ;C语言程序设计进阶篇11.6.2 11.6.2 共用体
60、类型的应用共用体类型的应用【例【例11.1011.10】设有一个教师与学生通用的表格,见表】设有一个教师与学生通用的表格,见表11.411.4。学生的数据中包括编号、姓名、年龄、职业及班级学生的数据中包括编号、姓名、年龄、职业及班级/ /职务,教师的数据包括编号、姓名、年龄、职业及职职务,教师的数据包括编号、姓名、年龄、职业及职务。编程输入人员数据,再输出它。务。编程输入人员数据,再输出它。C语言程序设计进阶篇#include stdio.hvoid main() int i; struct int num; char name10; int age; char job; union int
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高二年级下学期班级管理计划
- 高一上学期数学教学工作计划
- 高二化学选修五下学期教学进度计划
- 小学三年级课后辅导与提升计划
- 优化小学语文学习差距的计划
- 全国青少年足球活动计划
- 五年级体育课资源整合计划
- 二年级上册法治教育专题教学计划
- 三年级上册家长沟通交流计划
- 人教版二年级上册学生评估与反馈计划
- 常见含麻黄碱类药物目录
- Unit 4 Protecting our heritage sites 课文语篇填空-牛津译林版高中英语选择性必修第三册
- GB/T 16955-1997声学农林拖拉机和机械操作者位置处噪声的测量简易法
- GB/T 15593-2020输血(液)器具用聚氯乙烯塑料
- GB 16410-2007家用燃气灶具
- 铁碳合金的相图解读
- 2023年复旦大学博士研究生入学考试专家推荐信模板
- 中小学教师资格证面试课件讲义
- 全国初中英语优质课大赛一等奖《八年级Unit 6An old man》说课课件
- 湖北地区医院详细名单一览表
- 麦肯锡入职培训第一课:让职场新人一生受用的逻辑思考力新员工培训教材
评论
0/150
提交评论