结构体和共用体.ppt
普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材结构体和共用体 Still waters run deep.流静水深流静水深,人静心深人静心深 Where there is life,there is hope。有生命必有希望。有生命必有希望普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材 8.1 结构体结构体 8.2 动态内存分配与链表动态内存分配与链表 8.3 共用体类型共用体类型 8.4 枚举类型枚举类型 8.5 用户自定义类型用户自定义类型 8.6 程序举例程序举例第第8章章 结构体和共用体结构体和共用体普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材 8.1 结结 构构 体体普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体8.1.1 结构类型定义结构类型定义 在在实实际际问问题题中中,一一组组数数据据往往往往具具有有不不同同的的数数据据类类型型。例例如如,在在学学生生登登记记表表中中,姓姓名名应应为为字字符符型型;学学号号可可为为整整型型或或字字符符型型;年年龄龄应应为为整整型型;性性别别应应为为字字符符型型;成成绩绩可可为为整整型型或或实实型型。但但这这些些显显然然不不能能用用一一个个数数组组来来存存放放这这一一组组数数据据。因因为为数数组组中中各各元元素素的的类类型型和和长长度度都都必必须须一一致致,以以便便于于编编译译系系统统处处理理。为为了了解解决决这这个个问题,语言中给出了另一种构造数据类型问题,语言中给出了另一种构造数据类型“结构体结构体”。“结结构构体体”是是一一种种构构造造类类型型,它它是是由由若若干干“成成员员”组组成成的的。每每一一个个成成员员可可以以是是一一个个基基本本数数据据类类型型或或者者又又是是一一个个构构造造类类型型。结结构构体体既既然然是是一一种种“构构造造”而而成成的的数数据据类类型型,那那么么在在说说明明和和使使用用之之前前必必须须先先定定义义它它,也也就就是是构构造造它它。如如同同在在说说明明和和调调用用函函数数之前要先定义函数一样。之前要先定义函数一样。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体 定义一个结构体类型的一般形式为:定义一个结构体类型的一般形式为:struct 结构体名结构体名 结构成员的说明结构成员的说明;成员表由若干个成员组成,每个成员都是该结构体的一个组成成员表由若干个成员组成,每个成员都是该结构体的一个组成部分。对每个成员也必须作类型说明,其形式为:部分。对每个成员也必须作类型说明,其形式为:类型说明符类型说明符 成员名成员名;成员名的命名应符合标识符的书写规定。例如:成员名的命名应符合标识符的书写规定。例如: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 结构体类型变量的说明结构体类型变量的说明 说明结构体变量有以下三种方法。以上面定义的说明结构体变量有以下三种方法。以上面定义的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 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结结构构体体定定义义中中,所所有有的的成成员员都都是是基基本本数数据据类类型型或或数数组组类类型型。成成员员也也可可以以又又是是一一个个结结构构体体类类型型,即即构构成成了了嵌嵌套套的的结构体。结构体。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材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结结构构体体类类型型。成成员员名名可可与与程程序序中中其其它它变变量量同同名名,互互不不干干扰扰。结结构构体体变变量量成成员员的的表表示示方方法法,在在程程序序中中使使用用结结构构体体变变量量时时,往往不把它作为一个整体来使用。,往往不把它作为一个整体来使用。说说明明:结结构构体体在在内内存存中中存存储储容容量量是是各各成成员员容容量量之之和和,这这是是与与后后面面联合体的重要区别。联合体的重要区别。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体8.1.3 结构体变量的引用结构体变量的引用 一一般般情情况况下下,不不能能对对一一个个结结构构体体变变量量作作为为整整体体引引用用,只只能能引用其中的成员。结构体变量中成员引用的一般形式为:引用其中的成员。结构体变量中成员引用的一般形式为:结构体变量名结构体变量名.成员名成员名其其中中,“.”是是域域成成员员运运算算符符,是是C语语言言中中优优先先级级最最高高的的运运算算符符之一。之一。例例如如:boy1.num 即即第第一一个个人人的的学学号号,boy2.sex 即即第第二二个个人人的的性性别别。如如果果成成员员本本身身又又是是一一个个结结构构体体,则则必必须须逐逐级级找找到到最最低低级的成员才能使用。级的成员才能使用。例例如如:boy1.birthday.month 即即第第一一个个人人出出生生的的月月份份。成成员员可以在程序中单独使用,与普通变量完全相同。可以在程序中单独使用,与普通变量完全相同。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体8.1.4 结构体变量的赋值结构体变量的赋值对于结构体变量,只有以下两种情况可以对结构体变量赋值。对于结构体变量,只有以下两种情况可以对结构体变量赋值。(1)结构体变量整体赋值)结构体变量整体赋值 例如:例如:boy2=boy1;(2)取结构体变量地址)取结构体变量地址 例如:例如:&boy2;&boy1;注注意意:结结构构体体变变量量名名是是地地址址常常量量,含含义义与与数数组组名名和和函函数数名名相相同同,不能对结构体变量做整体输入不能对结构体变量做整体输入/输出。例如:输出。例如:scanf(%d,%s,%c,%f,&boy1);printf(%d,%s,%c,%f,boy1);这些语句都是不允许的,只能对结构体成员进行输入这些语句都是不允许的,只能对结构体成员进行输入/输出。输出。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材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);scanf(%c%f,&boy1.sex,&boy1.score);/*给给boy1的成员的成员sex和和score赋值赋值*/boy2=boy1;/*把把boy1整体赋给整体赋给boy2*/printf(number=%dnname=%sn,boy2.num,boy2.name);printf(sex=%cnscore=%6.2fn,boy2.sex,boy2.score);普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体程序运行结果:程序运行结果:input sex and score:M 96 number=102name=Zhang pingsex=Mscore=96.00 本本程程序序中中用用赋赋值值语语句句给给num和和name两两个个成成员员赋赋值值,name是是一一个个字字符符串串指指针针变变量量。用用scanf()函函数数动动态态地地输输入入sex和和score成成员员值值,然然后后把把boy1的的所所有有成成员员的的值值整整体体赋赋予予boy2。最最后后分分别别输出输出boy2 的各个成员值。的各个成员值。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体8.1.5 结构体变量的初始化结构体变量的初始化 如如果果结结构构体体变变量量为为全全局局变变量量或或者者静静态态变变量量,则则可可以以对对它它做做初初始始化化赋赋值值。对对局局部部或或自自动动结结构构体体变变量量不不能能做初始化赋值。做初始化赋值。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体例例8.2 外部结构体变量初始化。外部结构体变量初始化。#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=78.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,boy2.num,boy2.name);printf(sex=%cnscore=%6.2fn,boy2.sex,boy2.score);本程序是把本程序是把boy1,boy2都定义为静态局部的结构体变量,同都定义为静态局部的结构体变量,同样可以做初始化赋值。样可以做初始化赋值。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体8.1.6 结构体数组结构体数组 一一个个结结构构体体变变量量可可以以处处理理一一个个对对象象,如如果果有有多多个个对对象象,则则需需要要多多个个结结构构体体变变量量,数数组组的的元元素素也也可可以以是是结结构构体体类类型型的的,因因此此可可以以构构成成结结构构体体数数组组。结结构构体体数数组组的的每每一一个个元元素素都都是是具具有有相相同同结结构构体体类类型型的的下下标标结结构构体体变变量量。在在实实际际应应用用中中,经经常常用用结结构构体体数数组组来来表表示示具具有有相相同同数数据据结构的一个群体。如一个班的学生档案,一个车间职工的工资表等。结构的一个群体。如一个班的学生档案,一个车间职工的工资表等。结构体数组的定义方法和结构体变量相似,也有三种方式:结构体数组的定义方法和结构体变量相似,也有三种方式:(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;boy5;普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材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 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;/*对结构体数组元素初始化对结构体数组元素初始化*/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 结构体结构体程序运行结果:程序运行结果: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+)/*输入通讯录输入通讯录*/printf(input name:);gets(mani.name);printf(input phone:);gets(mani.phone);printf(NamettPhonen);for(i=0;i成员名成员名;例如:例如:(*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=&boy1;printf(number=%dnname=%sn,boy1.num,boy1.name);printf(sex=%cnscore=%6.2fnn,boy1.sex,boy1.score);printf(number=%dnname=%sn,(*pstu).num,(*pstu).name);printf(sex=%cnscore=%6.2fnn,(*pstu).sex,(*pstu).score);printf(number=%dnname=%sn,pstu-num,pstu-name);printf(sex=%cnscore=%6.2fnn,pstu-sex,pstu-score);普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.1 结构体结构体 本本程程序序序序定定义义了了一一个个结结构构体体类类型型stu,定定义义了了stu类类型型结结构构变变量量boy1 并并作作了了初初始始化化赋赋值值,还还定定义义了了一一个个指指向向stu类类型型结结构构体体的的指指针针变变量量pstu。在在main()函函数数中中,pstu被被赋赋予予boy1的的地地址址,因因此此pstu指指向向boy1。然然后后在在printf()语语句句内内用用三三种种形形式式输输出出boy1的各个成员值。的各个成员值。程序运行结果:程序运行结果:number=102name=Zhang pingsex=Mscore=78.50 普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表 我我们们存存储储数数量量比比较较多多的的同同类类型型或或同同结结构构的的数数据据时时,一一般般首首先先考考虑虑数数组组。然然而而在在实实际际应应用用中中,当当处处理理一一些些难难以以确确定定其其数数量量的的数数据据时时,如如果果用用数数组组来来处处理理,必必须须事事先先分分配配一一个个足足够够大大的的连连续续空空间间,以以保保证证数数组组元元素素数数量量充充分分够够用用,但但这这样样处处理理时时对对存存储储空空间间的的一一种种浪浪费费。C 语语言言使使用用动动态态内内存存分分配配来来解解决决这这样样的的问问题题,其其中中常常用用的的就就是是链链表表。链链表表是是一一种种常常见见的的数数据据结结构构,它它动动态态地地进进行行存存储储分分配配,并并且且可可以以方方便便而又简单地进行数据插入,删除等操作。而又简单地进行数据插入,删除等操作。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表8.2.1 链表的概念链表的概念 链链表表是是指指若若干干个个数数据据按按一一定定的的原原则则连连接接起起来来。这这个个原原则则为为:前前一一个个数数据据指指向向下下一一个个数数据据,只只有有通通过过前前一一个个数数据据项项才才能能找找到到下一个数据项。下一个数据项。链链表表有有一一个个“头头指指针针”(head),它它指指向向链链表表的的第第一一个个元元素素(数数据据项项)。链链表表的的一一个个元元素素称称为为一一个个“结结点点”(node)。结结点点中中包包含含两两部部分分内内容容,第第一一部部分分是是结结点点数数据据本本身身,如如图图8-1中中的的、所所示示。结结点点的的第第二二部部分分是是一一个个指指针针,它它指指向向下下一一个个结结点点。最最后后一一个个结结点点称称为为“表表尾尾”,表表尾尾结结点点的的指指针针不不指指向任何地址,因此为空(向任何地址,因此为空(NULL)。)。图图8-1 链表结构图链表结构图普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表 如果每个结点采用一个指针,将前一个结点的指针指向下如果每个结点采用一个指针,将前一个结点的指针指向下一个结点,这称为单链表。如果每个结点有两个指向其他结点一个结点,这称为单链表。如果每个结点有两个指向其他结点的指针,则称为双链表。本节主要讨论单链表的运算。的指针,则称为双链表。本节主要讨论单链表的运算。由以上简单链表可以看到,链表中的每个结点至少包含两由以上简单链表可以看到,链表中的每个结点至少包含两个域,一个域用来存放数据,其类型根据需存放的数据类型定个域,一个域用来存放数据,其类型根据需存放的数据类型定义。另一个域用来存放下一个结点的地址,因此必然是一个指义。另一个域用来存放下一个结点的地址,因此必然是一个指针类型,此指针的类型应该是所指向的表结点的结构体类型。针类型,此指针的类型应该是所指向的表结点的结构体类型。在在C语言中,可以用结构体类型来实现链表,例如:语言中,可以用结构体类型来实现链表,例如:struct student int long;float score;struct student*next;/*指向下一结点指向下一结点*/;其中其中next是结构体指针变量,用来存放下一个结点的地址,即是结构体指针变量,用来存放下一个结点的地址,即next是指向下一个结点。是指向下一个结点。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表8.2.2 动态存储分配动态存储分配 C语语言言允允许许在在函函数数执执行行部部分分的的任任何何地地方方使使用用动动态态存存储储分分配配函函数数开开辟辟或或收收回回存存储储单单元元,这这样样的的存存储储分分配配叫叫动动态态存存储储分分配配。动动态态分配使用自由、节约内存。分配使用自由、节约内存。链链表表是是动动态态分分配配存存储储空空间间的的,也也就就是是说说在在需需要要的的时时候候才才开开辟辟一一个个结结点点的的存存储储空空间间。在在C语语言言中中提提供供了了以以下下有有关关的的函函数数来来实实现现动动态态存存储储分分配配和和释释放放,这这些些函函数数包包含含在在“stdio.h”或或“malloc.h”中。中。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表1.malloc()函数(分配内存空间函数)函数(分配内存空间函数)调用形式为:调用形式为:void*malloc(size);其其作作用用是是在在内内存存中中动动态态获获取取一一个个大大小小为为size个个字字节节的的连连续续存存储储空空间间。该该函函数数将将返返回回一一个个void类类型型的的指指针针,若若分分配配成成功功,就就返返回回所分配的空间的起始地址,否则,就返回空指针(所分配的空间的起始地址,否则,就返回空指针(NULL)。)。2calloc函数(分配内存空间函数)函数(分配内存空间函数)调用形式为:调用形式为:void*calloc(unsigned n,unsigned size);其其作作用用是是在在内内存存中中动动态态获获取取n个个大大小小为为size个个字字节节的的存存储储空空间间。该该函函数数将将返返回回一一个个void类类型型的的指指针针,若若分分配配成成功功,就就返返回回内内存存单单元元的的起起始始地地址址,否否则则,返返回回空空指指针针(NULL)。用用该该函函数数可可以以动动态态地地获获取取一一个个一一维维数数组组空空间间,其其中中n为为数数组组元元素素个个数数,每每个个数组元素的大小为数组元素的大小为size个字节。个字节。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表3free()函数(释放内存空间函数)函数(释放内存空间函数)调用形式为:调用形式为:void free(void*p);其其作作用用是是释释放放由由p指指针针所所指指向向的的内内存存空空间间。即即系系统统回回收收,使使这这段段空空间间又又可可以以被被其其他他变变量量所所用用。指指针针变变量量p是是最最近近一一次次调调用用malloc()或或calloc()函数时返回的值,不能是任意的地址。函数时返回的值,不能是任意的地址。4.realloc函数函数 调用形式为:调用形式为:void*recalloc(void*p,unsigned size);其其作作用用是是将将p所所指指的的已已分分配配的的内内存存空空间间重重新新分分配配成成大大小小为为size个个字字节节的的空空间间。它它用用于于改改变变已已分分配配的的空空间间的的大大小小,可可以以增增减减单单元元数数。函函数数返返回回新新内内存存的的首首地地址址,如如果果内内存存不不够够,则则返返回回空空指指针针(NULL)。)。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表例例8.7 分配一块区域,输入一个学生数据。分配一块区域,输入一个学生数据。#include#include void main()struct stu /*定义结构体定义结构体*/int num;char*name;char sex;float score;*ps;/*定义一个结构体指针变量定义一个结构体指针变量ps*/ps=(struct stu*)malloc(sizeof(struct stu);ps-num=102;/*输入学生数据输入学生数据*/ps-name=Zhang ping;ps-sex=M;ps-score=62.5;printf(number=%dnname=%sn,ps-num,ps-name);printf(sex=%cnscore=%6.2fn,ps-sex,ps-score);free(ps);普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表程序运行结果:程序运行结果:number=102name=Zhang pingsex=Mscore=62.50 本本程程序序中中,定定义义了了结结构构体体类类型型stu,定定义义了了stu类类型型指指针针变变量量ps。然然后后分分配配一一块块stu大大内内存存区区,并并把把首首地地址址赋赋予予ps,使使ps指指向向该该区区域域。再再以以ps为为指指向向结结构构体体的的指指针针变变量量对对各各成成员员赋赋值值,并并用用printf()输输出出各各成成员员值值。最最后后用用free()函函数数释释放放ps指指向向的的内内存存空空间间。整整个个程程序序包包含含了了申申请请内内存存空空间间、使使用用内内存存空空间间、释释放放内存空间三个步骤,实现存储空间的动态分配。内存空间三个步骤,实现存储空间的动态分配。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表8.2.3 建立和输出链表建立和输出链表 所谓动态建立链表是指在程序执行过程中从无到有地建立所谓动态建立链表是指在程序执行过程中从无到有地建立链表,将一个个新生成的结点顺次链接入已建立的链表上,上链表,将一个个新生成的结点顺次链接入已建立的链表上,上一个结点的指针域存放下一个结点的起始地址,并给各结点数一个结点的指针域存放下一个结点的起始地址,并给各结点数据域赋值。据域赋值。所谓输出链表是将链表上各个结点的数据域中的值依次输所谓输出链表是将链表上各个结点的数据域中的值依次输出,直到链表结尾。出,直到链表结尾。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表例例8.8 以三个结构体变量为结点建立一个简单的链表并输出。以三个结构体变量为结点建立一个简单的链表并输出。#include struct node int data;struct node*next;void main()struct node a,b,c,*head,*p;head=&a;/*头结点指向头结点指向a结点结点*/a.data=5;a.next=&b;/*a结点指向结点指向b结点结点*/b.data=10;b.next=&c;/*b结点指向结点指向c结点结点*/c.data=15;c.next=NULL;/*c结点是尾结点结点是尾结点*/p=head;/*使使p指向指向a结点结点*/while(p!=NULL)printf(%d-,p-data);/*输出指针输出指针p所指向结点的数据所指向结点的数据*/p=p-next;/*使使p指向下一个结点指向下一个结点*/printf(NULLn);程序运行结果:程序运行结果:5-10-15-NULL普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表8.2.4 链表的基本操作链表的基本操作 链链表表的的基基本本操操作作包包括括,建建立立并并初初始始化化链链表表,遍遍历历访访问问链链表表(包包括括查查找找结结点点、输输出出结结点点等等),删删除除链链表表中中的的结结点点,在在链链表表中插入结点。链表的各种基本操作的步骤如下。中插入结点。链表的各种基本操作的步骤如下。1.建立链表建立链表 建立头结点(或定义头指针变量)。建立头结点(或定义头指针变量)。读取数据。读取数据。生成新结点。生成新结点。将数据存入结点的数据域中。将数据存入结点的数据域中。将新结点连接到链表中(将新结点地址赋给上一个结将新结点连接到链表中(将新结点地址赋给上一个结 点的指针域连接到链表)。点的指针域连接到链表)。重复步骤重复步骤,直到尾结点为止。,直到尾结点为止。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表2遍历访问链表遍历访问链表 输输出出链链表表即即顺顺序序访访问问链链表表中中各各结结点点的的数数据据域域,方方法法是是:从从头头结点开始,不断地读取数据和下移指针变量,直到尾结点为止。结点开始,不断地读取数据和下移指针变量,直到尾结点为止。3删除链表中的一个结点删除链表中的一个结点 找到要删除结点的前驱结点。找到要删除结点的前驱结点。将要删除结点的后驱结点的地址赋给要删除结点的前驱将要删除结点的后驱结点的地址赋给要删除结点的前驱 结点的指针域。结点的指针域。将要删除结点的存储空间释放。将要删除结点的存储空间释放。4在链表的某结点前插入一个结点在链表的某结点前插入一个结点 开辟一个新结点并将数据存入该结点的数据域。开辟一个新结点并将数据存入该结点的数据域。找到插入点结点。找到插入点结点。将新结点插入到链表中,将新结点的地址赋给插入点上将新结点插入到链表中,将新结点的地址赋给插入点上 一个结点的指针域,并将插入点的地址存入新结点的指一个结点的指针域,并将插入点的地址存入新结点的指 针域。针域。普通高等教育普通高等教育“十一五十一五”国家级规划教材国家级规划教材8.2 动态内存分配与链表动态内存分配与链表例例8.9 建立并输出一个学生成绩链表(假设学生成绩表中只含姓名和成绩)。建立并输出一个学生成绩链表(假设学生成绩表中只含姓名和成绩)。#include#include typedef struct student /*自自定定义义链链表表结结点点数数据据类类型型名名ST和和指指针针类类型型名名*STU*/char name20;int score;struct student*next;/*结点指针域结点指针域*/ST,*STU;STU createlink(int n)/*建立一个由建立一个由n个结点构成的单链表函数,返回结点指