1、 结构体结构体 与与 共用体共用体 结构体结构体 共用体共用体 枚枚 举举 第十一章第十一章 结构体与共用体结构体与共用体本章要求:本章要求:、掌握结构体的概念,会使用结构、掌握结构体的概念,会使用结构体指针,结构体数组。体指针,结构体数组。、链表的概念,熟练掌握用指针处、链表的概念,熟练掌握用指针处理链表。理链表。、了解共用体的概念。、了解共用体的概念。、了解枚举类型。、了解枚举类型。、会用、会用typedef定义新数据类型。定义新数据类型。11 111从基本数据类型到抽象数据类型从基本数据类型到抽象数据类型二进制数二进制数在早期的机器指令及汇编语言中,数据对象均用二进制数在早期的机器指令及
2、汇编语言中,数据对象均用二进制数表示,没有类型的概念表示,没有类型的概念基本数据类型基本数据类型在高级语言中引入了基本数据类型:在高级语言中引入了基本数据类型:整型、实型、字符型整型、实型、字符型等等基本数据类型不能方便的解决所有问题,基本数据类型不能方便的解决所有问题,用户自己构造数据类型用户自己构造数据类型-复合数据类型复合数据类型表示复杂的数据对象,表示复杂的数据对象,数组数组、指针指针也可算作此类,也可算作此类,然而最典然而最典型的代表就是型的代表就是“结构体结构体”,抽象数据类型(抽象数据类型(Abstract Data Type,简称,简称ADT)在复合数据类型基础上增加了对数据的
3、操作在复合数据类型基础上增加了对数据的操作类类跨时代的进步跨时代的进步2思考一个问题在程序里表示一个人(姓名、年龄、性别、在程序里表示一个人(姓名、年龄、性别、),),怎么表示?怎么表示?想表示多个人呢?想表示多个人呢?如何用计算机程序实现下述表格的管理?如何用计算机程序实现下述表格的管理?表11-1 某学校学生成绩管理表学学号号姓名姓名性性别别入学时间入学时间计算机计算机原理原理英英 语语数数 学学物物 理理1令狐冲令狐冲男男1999908372822林平之林平之男男1999789288783岳灵珊岳灵珊女女1999897298664任莹莹任莹莹女女1999789587905 6 3数组的解
4、决方法数组的解决方法int stuId30;/*最多可以管理最多可以管理30个学生个学生,每个每个 学生的学号用数学生的学号用数组的下标组的下标表示表示*/char stuName3010;char stuSex302;int timeOfEnter30;/*入学时间用入学时间用int表示表示*/int scoreCom30;/*计算机原理课的成绩计算机原理课的成绩*/int scoreEng30;/*英语课的成绩英语课的成绩*int scoreMath30;/*数学课的成绩数学课的成绩*/int scoreMus30;/*物理课的成绩物理课的成绩*/4数组的解决方法数据的内存管理方式 907
5、889788392729572889887827866901234令狐冲林平之岳灵珊任莹莹男男女女19991999199919995希望的内存分配图 1令狐冲令狐冲男1999908372822林平之林平之男1999789288783岳灵珊岳灵珊女1999897298664任莹莹任莹莹女1999789587906结构体的解决方法struct STUDENT int studID;/*每个学生的序号每个学生的序号*/char studName10;/*每个学生的姓名每个学生的姓名*/char studSex4;/*每个学生的性别每个学生的性别*/int timeOfEnter;/*每个学生的入学时
6、间每个学生的入学时间*/int scoreCom;/*每个学生的计算机原理成绩每个学生的计算机原理成绩*/int scoreEng;/*每个学生的英语成绩每个学生的英语成绩*/int scoreMat;/*每个学生的数学成绩每个学生的数学成绩*/int scoreMus;/*每个学生的物理成绩每个学生的物理成绩*/;struct STUDENT 是一个类型是一个类型struct STUDENT students4;students0.studentIDstudents0.scoreComputer它们都是变量,一般称为结构的成员变量它们都是变量,一般称为结构的成员变量7一、定义一个结构的一般形
7、式一、定义一个结构的一般形式在实际问题中,一组数据往往具有不同的数据类型。在实际问题中,一组数据往往具有不同的数据类型。例如,学生登记表中,例如,学生登记表中,姓名姓名应为应为学号学号可为可为年龄年龄应为应为性别性别应为应为成绩成绩可为可为另一种构造数据类型另一种构造数据类型“结构(结构(structure)”或叫或叫“结构体结构体”它相当于其它高级语言中的记录。它相当于其它高级语言中的记录。“结构结构”是一种构造类型,它是由若干是一种构造类型,它是由若干“成员成员”组成的。每一个成员可以是一个基本数组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。结构既是一种据类型或者又是一个构
8、造类型。结构既是一种“构造构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调用函数之前要先定义函数一样。造它。如同在说明和调用函数之前要先定义函数一样。显然不能用一个数组来存显然不能用一个数组来存放这一组数据。因为数组放这一组数据。因为数组中各元素的类型和长度都中各元素的类型和长度都必须一致,以便于编译系必须一致,以便于编译系统处理。为了解决这个问统处理。为了解决这个问题题第十一章结构体与共用体第十一章结构体与共用体字符型字符型;整型或字符型整型或字符型;整型或实型整型或实型;整型整型;字符型字符型;8
9、在这个结构定义中,结构名为stu,该结构由4个成员组成。第一个成员为num,整型变量;第二个成员为name,字符数组;第三个成员为sex,字符变量;第四个成员为score,实型变量。应注意在括号后的分号是不可少的。结构定义之后,即可进行变量说明。凡说明为结构stu的变量都由上述4个成员组成。由此可见 结构是一种复杂的数据类型,结构是一种复杂的数据类型,是数目固定,类型不同的若干是数目固定,类型不同的若干有序变量的集合。有序变量的集合。定义一个结构的一般形式为:定义一个结构的一般形式为:struct 结构名结构名 成员表列成员表列;成员表列由若干个成员组成,每个成员都是该结构的一成员表列由若干个
10、成员组成,每个成员都是该结构的一个组成部分。个组成部分。对每个成员也必须作类型说明对每个成员也必须作类型说明,其形式为:,其形式为:类型说明符类型说明符 成员名成员名;成员名的命名应符合标识符的书写规定成员名的命名应符合标识符的书写规定 struct stu int num;char name20;char sex;float score;例如:例如:复习复习:9二、结构类型变量的说明二、结构类型变量的说明说明结构变量有以下三种方法。以上面定义的说明结构变量有以下三种方法。以上面定义的stu为例来加为例来加以说明。以说明。、先定义结构,再说明结构变量、先定义结构,再说明结构变量如:如:说明了两
11、个变量说明了两个变量boy1和和boy2为为stu结构类型。也可以结构类型。也可以用宏定义使一个符号常量来表示一个结构类型。用宏定义使一个符号常量来表示一个结构类型。struct stu int num;char name20;char sex;float score;struct stu boy1,boy2;例如:例如:#define STU struct stuSTU int num;char name20;char sex;float score;STU boy1,boy2;102 2、在定义结构类型的同时说明结构变量、在定义结构类型的同时说明结构变量struct stu int num
12、;char name20;char sex;float score;boy1,boy2;这种形式的说明的一般形式为:这种形式的说明的一般形式为:struct 结构名结构名 成员表列成员表列 变量名表列变量名表列;结构类型变量结构类型变量例如:例如:还可以还可以定义定义 structstruct stustu boy3,boy4;11、直接说明结构变量、直接说明结构变量例如:例如:struct int num;char name20;char sex;float score;boy1,boy2;这种形式的说明的一般形式为:这种形式的说明的一般形式为:struct 成员表列成员表列变量名表列变量名
13、表列;结构类型变量结构类型变量第三种方法与第二种方法的区第三种方法与第二种方法的区别在于第三种方法中省去了结别在于第三种方法中省去了结构名,而直接给出结构变量。构名,而直接给出结构变量。12 说明了说明了boy1,boy2变量为变量为stu类型后,即可向这两个变量类型后,即可向这两个变量中的中的各个成员赋值各个成员赋值。在上述。在上述stu结构定义中,所有的成员都是结构定义中,所有的成员都是基本数据类型或数组类型。基本数据类型或数组类型。三种方法中说明的三种方法中说明的boy1,boy2变量都具有下图所示的结构:变量都具有下图所示的结构:13成员也可以又是一个结构,即构成了嵌套的结构。成员也可
14、以又是一个结构,即构成了嵌套的结构。例如,下图给出了另一个数据结构。例如,下图给出了另一个数据结构。struct int num;char name20;char sex;struct date birthday;float score;boy1,boy2;按图可给出以下结构定义:按图可给出以下结构定义:struct date int month;int day;int year;首先定义一个结构date,由month(月)、day(日)、year(年)三个成员组成。成员成员birthday被说明为被说明为data结构类型结构类型14 成员名可与程序中其它变量同名,互不干扰成员名可与程序中其它
15、变量同名,互不干扰。例例:struct yeardatestruct yeardate intint num;num;char name20;char name20;char sex;char sex;structstruct date birthday;date birthday;float score;float score;boy1,boy2;boy1,boy2;intint score;score;15三、结构变量成员的表示方法三、结构变量成员的表示方法 在程序中使用结构变量时在程序中使用结构变量时,往往不把它作为一个整体来往往不把它作为一个整体来使用。在使用。在ANSI C中除了允许
16、具有相同类型的结构变量相互中除了允许具有相同类型的结构变量相互赋值以外,一般对结构变量的使用,包括赋值、输入、输出、赋值以外,一般对结构变量的使用,包括赋值、输入、输出、运算等都是通过结构变量的成员来实现的。运算等都是通过结构变量的成员来实现的。表示结构变量成员的一般形式是:表示结构变量成员的一般形式是:结构变量名结构变量名.成员名成员名如果成员本身又是一个结构则必须逐级找到最低级的成如果成员本身又是一个结构则必须逐级找到最低级的成员才能使用。员才能使用。即第一个人出生的月份成员可以在程序中单独使用,与普通变量完即第一个人出生的月份成员可以在程序中单独使用,与普通变量完全相同。全相同。例如:例
17、如:boy1.num 即第一个人的学号即第一个人的学号 boy2.sex 即第二个人的性别即第二个人的性别例如:例如:boy1.birthday.month16四、结构变量的赋值四、结构变量的赋值结构变量的赋值就是给各成员赋值。可用输入语句或结构变量的赋值就是给各成员赋值。可用输入语句或赋值语句来完成。赋值语句来完成。【例例11.1】给结构变量赋值并输出其值。给结构变量赋值并输出其值。main()structstruct stustu intint num;num;char char*name;name;char sex;char sex;float score;float score;boy
18、1,boy2;boy1,boy2;boy1.num=102;boy1.name=Zhang ping;printf(“输入输入性别性别and分数分数n“);scanf(%c%f,&boy1.sex,&boy1.score);boy2=boy1;printf(“学号学号=%dn姓名姓名=%sn,boy2.num,boy2.name);printf(“性别性别=%cn分数分数=%fn,boy2.sex,boy2.score);u用赋值语句给用赋值语句给num和和name两个成员赋值两个成员赋值uname是一个字符串指针变量是一个字符串指针变量u用用scanf函数动态地输入函数动态地输入sex和和s
19、core成员值成员值u然后把然后把boy1的所有成员的值整体赋予的所有成员的值整体赋予boy2u最后分别输出最后分别输出boy2的各个成员值的各个成员值本例表示了结构变量的赋值、输入和输出的方法本例表示了结构变量的赋值、输入和输出的方法17五、结构变量的初始化五、结构变量的初始化和其他类型变量一样,结构变量可以在定义时进行初始化赋值。和其他类型变量一样,结构变量可以在定义时进行初始化赋值。【例例11.211.2】对结构变量初始化。对结构变量初始化。main()struct stu /*定义结构定义结构*/int num;char*name;char sex;float score;boy2,b
20、oy1=102,Zhang ping,M,78.5 ;boy2=boy1;printf(Number=%dnName=%sn,boy2.num,boy2.name);printf(Sex=%cnScore=%fn,boy2.sex,boy2.score);18六、结构数组的定义六、结构数组的定义 数组的元素也可以是结构类型的。因此可以构成结构型数组的元素也可以是结构类型的。因此可以构成结构型数组。结构数组的数组。结构数组的每一个元素都是具有相同结构类型的下每一个元素都是具有相同结构类型的下标结构变量标结构变量。在实际应用中,经常用结构数组来表示具有相同数据结在实际应用中,经常用结构数组来表示具
21、有相同数据结构的一个群体。如一个班的学生档案,一个车间职工的工资构的一个群体。如一个班的学生档案,一个车间职工的工资表等。表等。方法和结构变量相似,只需说明它为数组类型即可方法和结构变量相似,只需说明它为数组类型即可。struct stu int num;char *name;char sex;float score;boy5;定义了一个结构数组定义了一个结构数组 boy,共有共有5个元素个元素:boy0boy4每个数组元素都具有每个数组元素都具有 struct stu 的结构形式的结构形式例如:例如:19struct stu int num;char*name;char sex;float
22、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;对结构数组可以作初始化赋值。对结构数组可以作初始化赋值。例如:例如:当对全部元素作初始化赋值时,也可不给出数组长度。当对全部元素作初始化赋值时,也可不给出数组长度。20【例例11.3】计算学生的平均成绩和不及格的人数。计算学生的平均成绩和不及格的人数。struct stu int num;char*name;char sex;float score;boy5=101,Li ping
23、,M,45,102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58;main()int i,c=0;float ave,s=0;for(i=0;i5;i+)s+=boyi.score;if(boyi.score60)c+=1;printf(s=%fn,s);ave=s/5;printf(“平均分平均分=%fn人数人数=%dn”,ave,c);定义了一个外部结构数组boy,共5个元素,并作了初始化赋值。在main函数中用for语句逐个累加各元素的score 成员值存于s之中,如score的值小
24、于60(不及格)即计数器C加1,循环完毕后计算平均成绩,并输出全班总分,平均分及不及格人数。21【例例11.4】建立一个简易的同学通讯录建立一个简易的同学通讯录main()struct mem manNUM;int i;for(i=0;iNUM;i+)printf(“输入姓名输入姓名:n);gets(mani.name);printf(“输入电话号码输入电话号码:n);gets(mani.phone);printf(nametttphonenn);for(i=0;i-成员名成员名例如:例如:(*pstu).num 或者:或者:pstu-num注意注意(*pstu)两侧的括号不可少,因为成员符两
25、侧的括号不可少,因为成员符“.”的优先的优先级高于级高于“*”。去掉括号写作去掉括号写作*pstu.num*(pstu.num),意义就完全不对了。,意义就完全不对了。25下面通过例子来说明结构指针变量的具体说明和使用方法。下面通过例子来说明结构指针变量的具体说明和使用方法。struct stu int num;char*name;char sex;float score;boy1boy1=102,Zhang ping,M,78.5,*pstupstu;【例例11.5】boy1pstu26main()pstu=&boy1;printf(“学号学号=%dn姓名姓名=%sn,boy1.num,bo
26、y1.name);printf(“性别性别=%cn分数分数=%fnn”,boy1.sex,boy1.score);printf(“学号学号=%dn姓名姓名=%sn,(*pstu).num,(*pstu).name);printf(“性别性别=%cn分数分数=%fnn,(*pstu).sex,(*pstu).score);printf(“学号学号=%dn姓名姓名=%sn,pstu-num,pstu-name);printf(“性别性别=%cn分数分数=%fnn,pstu-sex,pstu-score);27定义了一个结构定义了一个结构stu,定义了,定义了stu类型结构变量类型结构变量boy1并
27、作了并作了初始化赋值,还定义了一个指向初始化赋值,还定义了一个指向stu类型结构的指针变量类型结构的指针变量pstu。在。在main函数中,函数中,pstu被赋予被赋予boy1的地址,因此的地址,因此pstu指向指向boy1。然后在。然后在printf语句内用三种形式输出语句内用三种形式输出boy1的各的各个成员值。从运行结果可以看出:个成员值。从运行结果可以看出:结构变量结构变量.成员名成员名 boy1.numboy1.num (*结构指针变量结构指针变量).成员名成员名(*pstupstu).num).num 结构指针变量结构指针变量-成员名成员名 pstupstu-num-num这三种用
28、于表示结构成员的形式是完全等效的。这三种用于表示结构成员的形式是完全等效的。282、指向结构数组的指针、指向结构数组的指针 指针变量可以指向一个结构数组,这时结构指针变量指针变量可以指向一个结构数组,这时结构指针变量的值是整个结构数组的首地址。结构指针变量也可指向结的值是整个结构数组的首地址。结构指针变量也可指向结构数组的一个元素,这时结构指针变量的值是该结构数组构数组的一个元素,这时结构指针变量的值是该结构数组元素的首地址。元素的首地址。设设ps为指向结构数组的指针变量为指向结构数组的指针变量 则则 ps也指向该结构数组的也指向该结构数组的0号元素号元素 ps+1指向指向1号元素号元素 ps
29、+i则指向则指向i号元素号元素 【例例11.6】用指针变量输出结构数组。用指针变量输出结构数组。104.103.102101.psps+iboy29struct stu int num;char*name;char sex;float score;boy5=101,Zhou ping,M,45,102,Zhang ping,M,62.5,103,Liou fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58,;main()struct stu *ps;printf(“学号:姓名:性别:分数学号:姓名:性别:分数n);for(ps=boy;psnu
30、m,ps-name,ps-sex,ps-score);30 在程序中,定义了在程序中,定义了stu 结构类型的结构类型的外部数组外部数组 boy并作并作了初始化赋值。在了初始化赋值。在main函数内定义函数内定义ps为指向为指向stu类型的指类型的指针。在循环语句针。在循环语句for的表达式的表达式1中,中,ps 被赋予被赋予 boy 的首地址,的首地址,然后循环然后循环5次,输出次,输出boy数组中各成员值。数组中各成员值。注意的是,注意的是,一个一个结构指针变量虽然可以用来访问结构结构指针变量虽然可以用来访问结构变量或结构数组元素的成员变量或结构数组元素的成员,但是,不能使它指向一个成,但
31、是,不能使它指向一个成员。也就是说不允许取一个成员的地址来赋予它。员。也就是说不允许取一个成员的地址来赋予它。如:如:ps=&boy1.sex;赋值错误赋值错误 只能是:只能是:ps=boy;赋予数组首地址赋予数组首地址 或者是:或者是:ps=&boy0;赋予赋予0号元素首地址号元素首地址313、结构指针变量作函数参数、结构指针变量作函数参数 在在ANSI C 标准中允许用结构变量作函数参数进行标准中允许用结构变量作函数参数进行整体传送。但是这种传送要将全部成员逐个传送,特整体传送。但是这种传送要将全部成员逐个传送,特别是成员为数组时将会使传送的时间和空间开销很大,别是成员为数组时将会使传送的
32、时间和空间开销很大,严重地降低了程序的效率。因此最好的办法就是使用严重地降低了程序的效率。因此最好的办法就是使用指针,即指针,即用指针变量作函数参数进行传送。这时用指针变量作函数参数进行传送。这时由实参传向形参的只是地址由实参传向形参的只是地址,从而减少了时间,从而减少了时间和空间的开销。和空间的开销。32【例例11.7】计算一组学生的平均成绩和不及格人数。计算一组学生的平均成绩和不及格人数。用结构用结构指针指针变量作函数参数编程。变量作函数参数编程。struct stu int num;char*name;char sex;float score;boy5=101,Li ping,M,45,
33、102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58,;main()struct stu*ps;void aveave(struct stu*ps);ps=boy;ave(ps);void aveave(struct stu*ps)int c=0,i;float ave,s=0;for(i=0;iscore;if(ps-score60)c+=1;printf(s=%fn,s);ave=s/5;printf(“平均分数平均分数=%fn人数人数=%dn,ave,c);关键!关键!s=s+boy
34、i.score33 程序中定义了函数程序中定义了函数 ave,其形参为结构指针变量,其形参为结构指针变量ps。boy被定义为外部结构数组,因此在整个源程序中有效。被定义为外部结构数组,因此在整个源程序中有效。在在main函数中定义说明了结构指针变量函数中定义说明了结构指针变量ps,并把并把boy的首的首地址赋予它地址赋予它,使使ps指向指向boy数组。然后以数组。然后以ps作实参调用函作实参调用函数数ave。在函数。在函数ave中完成计算平均成绩和统计不及格人中完成计算平均成绩和统计不及格人数的工作并输出结果。数的工作并输出结果。由于本程序全部采用指针变量作运算和处理由于本程序全部采用指针变量
35、作运算和处理,故速度故速度更快,程序效率更高。更快,程序效率更高。34main()struct STUDENT *pt;float sum4=0.0,average4=0.0;int i;char*name=Computer,English,Math,Music“;pt=stu;/*pt指向结构体数组的第一个元素*/for(pt=stu;ptComputer;/*计算第一门课的成绩总和*/sum1=sum1+pt-English;/*计算第二门课的成绩总和*/sum2=sum2+pt-Math;/*计算第三门课的成绩总和*/sum3=sum3+pt-Music;/*计算第四门课的成绩总和*/f
36、or(i=0;i4;i+)averagei=sumi/30;/*求每门功课的平均成绩*/printf(%20s:%4.2fn,namei,*(average+i);/*输出四门课的平均成绩*/struct STUDENT intstudentID;char studentName10;charstudentSex4;struct dat timeOfEnter;int Computer;int English;int Math;int Music;struct STUDENT stu30=1,令狐冲,男,1999,12,20,90,83,72,82,2,林平之,男,1999,07,06,78,
37、92,88,78,3,岳灵珊,女,1999,07,06,89,72,98,66,4,任莹莹,女,1999,07,06,78,95,87,90 ;#include struct dat intyear;intmonth;intday;35八、动态存储分配八、动态存储分配 在数组一章中,曾介绍过数组的长度是预先定义好的,在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。语言中不允许动态数组类型。在整个程序中固定不变。语言中不允许动态数组类型。例如:例如:int n;scanf(%d,&n);int an;在实际的编程中,往往会发生这种情况,即在实际的编程中,往往会发生这种情况,
38、即所需的内所需的内存空间取决于实际输入的数据,而无法预先确定。存空间取决于实际输入的数据,而无法预先确定。对于这对于这种问题,用数组的办法很难解决。为了解决上述问题,种问题,用数组的办法很难解决。为了解决上述问题,语言提供了一些内存管理函数,这些内存管理函数可以按语言提供了一些内存管理函数,这些内存管理函数可以按需要动态地分配内存空间,也可把不再使用的空间回收待需要动态地分配内存空间,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。用,为有效地利用内存资源提供了手段。用变量表示长度,用变量表示长度,想对数组的大小作想对数组的大小作动态说明,这是错动态说明,这是错误的。误的。36常
39、用的内存管理函数有以下四个:常用的内存管理函数有以下四个:(1 1)分配内存空间函数)分配内存空间函数malloc malloc (见见P387)P387)函数原形式:函数原形式:void*malloc(unsigned size)功能:功能:在内存的动态存储区中分配一块长度为在内存的动态存储区中分配一块长度为size“字节的连续区域。函数的返回值为该区域的首字节的连续区域。函数的返回值为该区域的首 地址。如内存不够地址。如内存不够,返回返回0。调用形式:调用形式:(类型说明符类型说明符*)malloc(size)“类型说明符类型说明符”表示把该区域用于何种数据类型。表示把该区域用于何种数据类
40、型。(类型说明符类型说明符*)表示把返回值强制转换为该类型指针。表示把返回值强制转换为该类型指针。“size”是一个无符号数。是一个无符号数。例如:例如:pc=(char*)malloc(100);Size字节字节地址地址表示分配表示分配100个字节的内存空间,个字节的内存空间,并强制转换为字符数组类型,函数并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,的返回值为指向该字符数组的指针,把该指针赋予指针变量把该指针赋予指针变量pc。37说明说明:如果函数未能成功地执行如果函数未能成功地执行(如自由内存不足等如自由内存不足等),则不能获,则不能获 得需要的存储空间,将返回一个空指针
41、得需要的存储空间,将返回一个空指针NULL,表示分,表示分配配 失败。失败。格式格式(类型说明符类型说明符*)malloc(size)中的中的(类型说明符类型说明符*)通常为通常为void类型的指针,表示如需要引用此地址,可用类型的指针,表示如需要引用此地址,可用类类 型转换成需要类型的指针。型转换成需要类型的指针。应使用的头部文件有应使用的头部文件有“malloc.h”例例:float*p;p=(float*)malloc(sizeof(float);38例例:#include”malloc.h”#include“string.h”main()char*p;unsigned size=20;
42、p=(char*)malloc(size);strcpy(p p,“Very good!”);printf(“%s”,p p);free(p);由于计算机可供用由于计算机可供用动态分配的内存空间是动态分配的内存空间是有限的,内存动态分配有限的,内存动态分配失败将导致指针变量值失败将导致指针变量值为为NULL,因而一般在,因而一般在调用函数时进行内存动调用函数时进行内存动态分配时须检查其返回态分配时须检查其返回值是否为值是否为NULL。char*p;p=malloc(20);if(!p)printf(“out of memoryn”);exit(1);if(p=NULL)39申请一个结构体的内存
43、通常:通常:struct temp int data;char name10;char sex;float score;;struct temp stu,*pt=&stu;而今:而今:struct temp int data;char name10;char sex;float score;;struct temp*pt;=(=(40(2 2)分配内存空间函数)分配内存空间函数 calloccalloc 函数原形式函数原形式:void void*calloccalloc(unsigned n,unsigned(unsigned n,unsigned size)size)调用形式调用形式:(类型
44、说明符类型说明符*)calloccalloc(n,size)(n,size)功能功能:在内存动态存储区中分配在内存动态存储区中分配n块长度为块长度为“size”字节字节 的连续区域。函数的返回值为该区域的首地址。的连续区域。函数的返回值为该区域的首地址。(类型说明符类型说明符*)用于强制类型转换。用于强制类型转换。calloc函数与函数与malloc 函数的区别仅在于一次可以分配函数的区别仅在于一次可以分配n块区域。块区域。例如:例如:psps=(=(structstruct stustu*)calloccalloc(3,(3,sizeofsizeof(structstruct stustu)
45、;);其中的其中的sizeof(struct stu)是求是求stu的结构长度。因此该语句的意思是:的结构长度。因此该语句的意思是:按按stustu的长度分配的长度分配3 3块连续区域块连续区域,强制转换为强制转换为stu类型类型,并把其首并把其首地址赋予指针变量地址赋予指针变量ps。Size字节字节地址地址Size字节字节Size字节字节41(3 3)释放内存空间函数)释放内存空间函数freefree 调用形式:调用形式:free(void*ptr);功能:功能:释放释放ptr所指向的一块内存空间,所指向的一块内存空间,ptr是一个任意类是一个任意类 型的指针变量型的指针变量,它它指向被释放
46、区域的首地址指向被释放区域的首地址。被释。被释 放区应是由放区应是由malloc或或calloc函数所分配的区域。函数所分配的区域。【例例11.8】分配一块区域,输入一个学生数据。分配一块区域,输入一个学生数据。main()struct stu int num;char*name;char sex;float score;*ps;psps=(=(structstruct stustu*)mallocmalloc(sizeofsizeof(structstruct stustu););ps-num=102;ps-name=Zhang ping;ps-sex=M;ps-score=62.5;pri
47、ntf(“学号学号=%dn姓名姓名=%sn,ps-num,ps-name);printf(“性别性别=%cn分数分数=%fn”,ps-sex,ps-score);free(ps);42#include malloc.hmain()float *ps,*p,i=1.0 ps=(float*)malloc(5*sizeof(float);p=ps;for(j=0;j5;j+)*ps+=i+;ps=p;for(j=0;j成员名成员名#define NULL 0#define TYPE struct stu#define LEN sizeof(struct stu)TYPE boy,*p;p p=(T
48、YPE*)malloc(LEN);stuend.sex=f,pt-sex=f (*pt).Sex=f 45struct类型的特点一个一个struct的类型的类型可以定义该类型的变量、数组、指针可以定义该类型的变量、数组、指针可以做函数的参数类型和返回值类型可以做函数的参数类型和返回值类型它的成员可以是任意类型它的成员可以是任意类型 基本类型、基本类型、数组、指针、结构体、共用体数组、指针、结构体、共用体struct类型的变量类型的变量两个结构体变量之间可以相互赋值两个结构体变量之间可以相互赋值 所以做为函数的参数时,是传值调用所以做为函数的参数时,是传值调用可以取地址可以取地址&不可能直接参与
49、算术和比较运算不可能直接参与算术和比较运算面向对象和数据库是面向对象和数据库是struct的思想的发展的思想的发展46思考下面的结构是什么意思?下面的结构是什么意思?struct temp int data;struct temp pt;下面的结构是什么意思呢?下面的结构是什么意思呢?struct temp int data;struct temp*pt;用于存放地址的成员,常把它称为用于存放地址的成员,常把它称为指针域指针域。47九、链表的概念九、链表的概念采用了动态分配的办法为一个结构分配内存空间。每一采用了动态分配的办法为一个结构分配内存空间。每一次分配一块空间可用来存放一个学生的数据,
50、我们可称之为次分配一块空间可用来存放一个学生的数据,我们可称之为一个一个结点结点。有多少个学生就应该申请分配多少块内存空间,有多少个学生就应该申请分配多少块内存空间,也就是说要建立多少个结点。也就是说要建立多少个结点。当然用结构数组也可以完成当然用结构数组也可以完成上述工作,但如果预先不能准确把握学生人数,也就无法确上述工作,但如果预先不能准确把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占定数组大小。而且当学生留级、退学之后也不能把该元素占用的空间从数组中释放出来。用的空间从数组中释放出来。48 用动态存储的方法可以很好地解决这些问题。有一用动态存储的方法可以很好
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。