1、第9章结构体、共用体与自定义类型-2-结构体的概念结构体数组指向结构体类型数据的指针共用体用typedef定义类型程序设计举例本章教学内容:本章教学内容:本章教学目标:本章教学目标:理解和掌握结构体类型的定义、结构体变量的定义与初始化、结构体变量成员的引用。理解和掌握结构体数组的定义、初始化及应用。理解和掌握指向结构体变量的指针及指向结构体数组的指针。了解共用体类型的定义、共用体变量的定义及引用。能够熟练用typedef定义数据类型。-3-9.1结构体的概念结构体的概念有时需要使用由多种类型数据组合而成的一种构造型数据。例如,要反映一个学生的基本情况,需要表示出的数据有学生的学号、姓名、性别、
2、年龄、成绩等数据项,这些数据项相互联系,共同构成一个整体。而这些数据项的数据类型又各不相同,这就要求定义出一种构造型数据,该构造型数据中的每一个分项的数据类型可以各不相同。在这种情况下,结构体类型便应运而生。-4-结构体类型的定义结构体类型的定义结构体类型是用户在程序中自己定义的一种数据类型。结构型必须先定义,然后利用已经定义好的结构型来定义变量、数组、指针等。定义结构体类型的一般形式为:struct结构体类型名结构体类型名数据类型数据类型1成员名成员名1;数据类型数据类型2成员名成员名2;数据类型数据类型3成员名成员名3;数据类型数据类型n成员名成员名n;-5-结构体类型的定义结构体类型的定
3、义例如,定义一个结构体类型student,如下:structstudentintnumber;charname10;charsex;intage;floatscore;-6-结构体类型的定义结构体类型的定义【例题例题9-1】结构体型嵌套的例子。为了存放一个人的姓名、性别,出生日期、年龄,可以定义以下的嵌套结构体型。structbirthdayinty;intm;intd;structpersoncharname10;charsex;structbirthdaybir;doublewage;-7-9.1.2结构体类型变量的定义及初始化结构体类型变量的定义及初始化结构体类型变量的定义一般有三种形式
4、:(1)先定义结构体类型,再定义结构体类型的变量。先定义结构体类型,再定义结构体类型的变量。定义结构体类型变量的一般形式为:定义结构体类型变量的一般形式为:结构体类型名结构体类型名结构体变量名;结构体变量名;例如:例如:【例题例题9-2】定义描述学生信息(学号、姓名、性别、年龄、成绩)的结构型及2个该结构型的变量,程序代码段如下:structstudentintnumber;charname10;charsex;intage;floatscore;structstudentstu1,stu2;-8-结构体类型变量的定义及初始化(续)(2)定义结构型的同时定义结构体变量及初始化定义结构型的同时定
5、义结构体变量及初始化可以在定义结构型的同时定义结构体变量及初始化,这种定义的一般形式为:-9-struct结构体名结构体名数据类型数据类型1成员名成员名1;数据类型数据类型2成员名成员名2;数据类型数据类型3成员名成员名3;数据类型数据类型n成员名成员名n;变量名表列及赋初值;变量名表列及赋初值;structstudentintnumber;charname10;charsex;intage;floatscore;stu1=1001,“yang”,F,21,98.5,stu2=1002,“zhang”,M,20,86.0;结构体类型变量的定义及初始化结构体类型变量的定义及初始化(续)(续)(3
6、)可以省略结构体名,定义结构体型的同时定义变量并赋初值可以省略结构体名,定义结构体型的同时定义变量并赋初值。这种定义的一般形式为:-10-struct数据类型1成员名1;数据类型2成员名2;数据类型3成员名3;数据类型n成员名n;变量名表列及赋初值;structintnumber;charname10;charsex;intage;floatscore;stu1=1001,“yang”,F,21,98.5,stu2=1002,“zhang”,M,20,86.0;9.1.3结构体类型变量成员的引用结构体类型变量成员的引用定义好结构体变量后,就可以使用变量了。一般不能直接使用结构体变量,只能引用结
7、构体变量的成员。引用结构体变量成员的一般形式如下:结构体变量名结构体变量名.成员名成员名-11-9.1.3结构体类型变量成员的引用结构体类型变量成员的引用(续)(续)-12-【例例9-3】引用结构体变量成员的例子。#include#includeintmain()structstudentintnumber;charname10;charsex;doublescore2;structstudents1;s1.number=2015001;strcpy(s1.name,yang);s1.sex=F;s1.score0=94.5;s1.score1=87.5;printf(number=%d,na
8、me=%s,sex=%c,s1.number,s1.name,s1.sex);printf(score1=%.2lf,score2=%.2lfn,s1.score0,s1.score1);return0;程序的运行结果如下图9-1所示:9.1.3结构体类型变量成员的引用结构体类型变量成员的引用(续)(续)在引用结构体变量的成员时,应注意以下几点:(1)不能整体引用结构体变量,只能对结构体变量的成员分别引用。如上例9-3中,输出语句若写成下列形式,则是错误的。printf(number=%d,name=%s,sex=%c,score1=%.2lf,score2=%.2lfn,s1);(2)结构体
9、变量的成员可以象普通的变量一样参加各种运算。例如:s1.score0=s1.score0+10;s1.score0=s1.score1;(3)可以引用结构体变量的地址,也可以引用结构体变量成员的地址。下列表示都是正确的。scanf(“%d”,&s1.number);/输入s1.number(学生的学号)值。printf(“%x”,&s1);/输出s1的起始地址。但注意,要输入结构体变量成员的值,应该分别输入各个成员值,不能整体读入结构体变量。下列形式是错误的:scanf(“%d,%s,%c,%lf,%lf”,s1);(4)对于嵌套的结构体变量,应用成员运算符,一级一级引用,直到找到最低一级成员
10、,只能对最低级成员进行各种运算。例如,stu1.name;stu1.bir.y;/表示学生stu1出生的年份。-13-嵌套的结构体变量成员引用-14-【例【例9-4】嵌套的结构体变量成员引用的例子】嵌套的结构体变量成员引用的例子。#include#includestructbirthdayintyear;intmonth;intday;structpersoncharname10;charsex;structbirthdaybir;charaddress30;p;intmain()strcpy(p.name,zhang);p.sex=M;p.bir.year=1995;p.bir.month=
11、10;p.bir.day=21;strcpy(p.address,shanghai);printf(name=%s,sex=%c,address=%sn,p.name,p.sex,p.address);printf(birthday=%4d年%2d月%2d日n,p.bir.year,p.bir.month,p.bir.day);return0;9.2结构体数组结构体数组结构体数组中的每一个元素相当于一个具有相同结构体类型的变量,结构体数组是具有相同类型的结构体变量的集合。9.2.1结构体数组的定义结构体数组的定义定义结构体数组的方法与定义结构体变量的方法一样,把变量名改为数组即可,定义结构体数
12、组也有三种方式。在此省去。-15-9.2.2结构体数组的初始化结构体数组的初始化对结构体数组的初始化,要分别对每一个数组元素初始化。structstudentintnumber;charname10;charsex;doublescore2;structstudentstu5=2015001,“zhang”,T,67.5,89.5,2015002,“liu”,F,80.0,86.5,2015003,“sun”,T,85.0,81.0,2015004,“yang”,F,72.0,75.5,2015005,“li”,T,86.0,75.0;-16-9.2.3结构体数组应用举例结构体数组应用举例-1
13、7-【例【例9-4】设有如下学生信息:学号、姓名、出生年月】设有如下学生信息:学号、姓名、出生年月(包含整型的年、月、日包含整型的年、月、日)。编写一程序,输入编写一程序,输入5个学生的信息,输出所有学生的学号和姓名个学生的信息,输出所有学生的学号和姓名。#defineN5#includeintmain()structbirthdayintyear;intmonth;intday;structdatelongnum;charname10;structbirthdaybir;stuN;for(inti=0;iN;i+)printf(请输入第%d个学生信息n,i+1);scanf(%ld,&stu
14、i.num);scanf(%s,stui.name);scanf(%d,%d,%d,&stui.bir.year,&stui.bir.month,&stui.bir.day);printf(n);printf(学号姓名n);for(i=0;i结构体成员名结构体成员名(3)结构体变量结构体变量.成员名成员名-19-指向结构体变量的指针指向结构体变量的指针-20-【例【例9-6】使用指向结构体变量的指针输出学生信息。】使用指向结构体变量的指针输出学生信息。#include#includestructstudentlongnum;charname10;charsex;intage;doublesco
15、re;intmain()structstudentstu1;structstudent*p;p=&stu1;stu1.num=20150101;strcpy(stu1.name,”ZhangJun”);stu1.sex=M;stu1.age=21;stu1.score=92.5;printf(“第一次输出学生信息:n”);printf(“num:%ld,name:%s,sex:%c,age:%d,score:%ldn”,p-num,p-name,p-sex,p-age,p-score);printf(“第二次输出学生信息:n”);printf(“num:%ld,name:%s,sex:%c,a
16、ge:%d,score:%ldn”,(*p).num,(*p).name,(*p).sex,(*p).age,(*p).score);printf(“第三次输出学生信息:n”);printf(“num:%ld,name:%s,sex:%c,age:%d,score:%ldn”,stu1.num,stu1.name,stu1.sex,stu1.age,stu1.score);return0;9.3.2指向结构体数组的指针指向结构体数组的指针指针变量可以指向一个结构体数组,此时结构体指针变量的值是整个结构体数组的首地址。结构体指针变量也可指向结构体数组中的某一个元素,此时结构体指针变量的值是该数组
17、元素的首地址。structstudentlongnum;charname10;charsex;intage;doublescore;structstudentstu5,*p;-21-9.3.2指向结构体数组的指针指向结构体数组的指针(续续)若执行p=stu;语句,则此时结构体指针p就指向了结构体数组stu的首地址。p是指向一维结构体数组的指针,对数组元素的引用有3种方法。(1)指针法。指针法。若p指向数组的某一个元素,则p-表示指针上移,指向前一个元素;p+表示指针下移,指向其后一个元素。例如:(+p)-name,先使p自加1,即指针指向下一个元素,然后取得它指向元素的name成员值。(p+)
18、-name,先得到p-name的值,然后使p自加1,指向下一个元素。请注意以上二者的区别。同样地:(-p)-name,先使p自减1,即指针指向上一个元素,然后取得它指向元素的name成员值。(p-)-name,先得到p-name的值,然后使p自减1,指向上一个元素。-22-9.3.2指向结构体数组的指针指向结构体数组的指针(续续)(2)地址法地址法。当执行p=stu;语句后,stu和p均表示数组的首地址,即第一个元素的地址&stu0;stu+i和p+i均表示数组第i个元素的地址,即&stui。数组元素各成员的引用形式为(stu+i)-num和(stu+i)-name,或者(p+i)-num和(
19、p+i)-name等。(3)指针的数组表示法指针的数组表示法若p=stu,则指针p指向数组stu,pi表示数组的第i个元素,pi与stui含义相同,都是表示数组的第i+1个元素。对数组成员的引用可表示为pi.num,pi.name等。-23-9.3.2指向结构体数组的指针指向结构体数组的指针(续续)-24-【例【例9-7】指向结构体数组的指针的应用。】指向结构体数组的指针的应用。#includestructstuintnum;char*name;charsex;floatscore;boy5=101,Zhouping,M,45,102,Zhangping,M,62.5,103,Lioufang
20、,F,92.5,104,Chengling,F,87,105,Wangming,M,58,;intmain()structstu*ps;for(ps=boy;psnum,ps-name,ps-sex,ps-score);return0;9.3.2指向结构体数组的指针指向结构体数组的指针(续续)-25-【例【例9-8】指向结构体数组的指针的应用。】指向结构体数组的指针的应用。#includestructdata/*定义结构体类型*/intday;intmonth;intyear;structstu/*定义结构体类型*/charname20;longnum;structdatabirthday;i
21、ntmain()inti;structstu*p,student4=liying,1,1978,5,23,wangping,2,1979,3,14,libo,3,1980,5,6,xuyan,4,1980,4,21;p=studentfor(i=0;iname,(p+i)-num,(p+i)-birthday.year,(p+i)-birthday.month,(p+i)-birthday.day);9.4共用体共用体在程序设计中,有时为了节约内存空间,要求某数据存储区在不同的时间分别存储不同类型的数据,后存储的类型数据会覆盖前一次存储的类型数据,这些不同的数据类型分时共享同一段内存单元,此时
22、可以用共用体来实现这种设计。在共用体中,所有的成员共享同一个内存空间,共用体长度是所有成员中长度最长的成员长度。-26-9.4.1共用体类型的定义共用体类型的定义共用体类型定义的一般形式为:union共用体名共用体名类型名类型名1成员名成员名1;类型名类型名2成员名成员名2;类型名类型名n成员名成员名n;说明:union是关键字,是共用体类型的标志。共用体的成员类型可以是基本数据类型,也可以是数组、指针、结构体或共用体类型等。共用体的所有成员共享同一个内存空间,共用体长度是所有成员中长度最长的成员长度。-27-例如,定义一种共用体类型data,如下:uniondatainti;charch;f
23、loatf;doubled;;定义了一种共用体类型data,该共用体类型有4个成员,共用体data的长度是最大成员d的长度8字节。9.4.2共用体变量的定义共用体变量的定义(1)在定义共用体类型的同时,定在定义共用体类型的同时,定义共用体变量。一般形式如下:义共用体变量。一般形式如下:union共用体类型名共用体类型名类型名类型名1成员名成员名1;类型名类型名2成员名成员名2;类型名类型名3成员名成员名3;变量名表列;变量名表列;-28-例如:例如:unionun_typeinta;floatb;charc;doubled;u1,u2;共用体变量的定义同结构体变量的定义一样,有如下共用体变量的
24、定义同结构体变量的定义一样,有如下3种形式:种形式:9.4.2共用体变量的定义共用体变量的定义(续续)(2)先定义共用体类型,再定义先定义共用体类型,再定义共共用体变量。一般形式如下:用体变量。一般形式如下:union共用体类型名共用体类型名类型名类型名1成员名成员名1;类型名类型名2成员名成员名2;类型名类型名3成员名成员名3;共用体类型名共用体类型名变量名列表;变量名列表;-29-上例也可改为:unionun_typeinta;floatb;charc;doubled;un_typeu1,u2;9.4.2共用体变量的定义共用体变量的定义(续续)(3)直接定义共用体类型的变量。一般形式如下:
25、union类型名类型名1成员名成员名1;类型名类型名2成员名成员名2;类型名类型名3成员名成员名3;变量名表列;变量名表列;-30-这种形式与第(1)种形式相比,省略了共用体类型名。上例也可写为:unioninta;floatb;charc;doubled;u1,u2;共用体变量的引用共用体变量的引用引用共用体变量的成员的方法与引用结构体变量的成员的方法一样,有三种形式:(1)共用体变量名.共用体成员名(2)共用体指针变量名-共用体成员名(3)(*共用体指针变量名).共用体成员名-31-共用体变量的引用共用体变量的引用(续续)【例9-9】共用体变量的引用。程序代码如下:#includeunio
26、naainta;charb;floatc;doubled;x;-32-intmain()x.a=10;printf(%dn,x.a);x.b=H;printf(%cn,x.b);x.c=87.5;x.d=98.5;printf(%f,%lfn,x.c,x.d);printf(n);return0;共用体变量的引用共用体变量的引用(续)(续)说明:(1)在共用体变量中,可以包含若干个类型不同的成员,但共用体成员不能同时使用。在每一时刻,只有一个成员及一种类型起作用,不能同时引用多个成员及多种类型。(2)共用体变量中起作用的成员值是最后一次存放的成员值,即共用体变量所有成员共用同一段内存单元,后来
27、存放的值将原先存放的值覆盖,故只能使用最后一次给定的成员值。(3)共用体变量的地址和它的各个成员的地址相同。(4)不能对共用体变量初始化和赋值,也不能企图引用共用体变量名来得到某成员的值。(5)共用体变量不能作函数参数,函数的返回值也不能是共用体类型。(6)共用体类型和结构体类型可以相互嵌套,共用体中成员可以为数组,甚至还可以定义共用体数组。-33-9.5用用typedef定义类型定义类型1.自定义基本类型自定义基本类型用户自定义类型的一般格式为:typedef原类型名原类型名新类型名;新类型名;表示用新类型名来代替原类型名。如:typedefintINTEGER;INTEGERa,b;这两句
28、等价于:inta,b;【例【例9-10】使用简单的自定义基本数据类型。#includetypedefintINTEGER;typedefcharCHARACTER;intmain()INTEGERa=15;/该语句相当于inta=15;CHARACTERb=M;/该语句相当于charb=M;return0;-34-9.5用用typedef定义类型定义类型(续)(续)2.自定义数组类型自定义数组类型利用自定义类型语句可以对数组类型定义为用户新类型。一般格式如下:typedef基本数据类型基本数据类型新类型名新类型名数组长度数组长度;功能:用“新类型”来定义由“基本数据类型符”声明的数组,数组的长
29、度为定义时说明的“数组长度”。【例9-11】自定义数组类型举例。#includetypedefintI_ARRAY20;typedefdoubleD_ARRAY10;intmain()I_ARRAYa=12,34,45,60,b=10,20,30,40;D_ARRAYm=34.5,67.8,89.0;return0;-35-9.5用用typedef定义类型定义类型(续)(续)3.自定义结构型自定义结构型利用自定义类型语句可以对程序中需要的结构型定义为一个用户新类型。一般格式如下:typedefstruct数据类型名数据类型名1成员名成员名1;数据类型名数据类型名2成员名成员名2;数据类型名数据
30、类型名3成员名成员名3;数据类型名数据类型名n成员名成员名n;用户新类型;用户新类型;功能:用“用户新类型”可以定义含有上述n个成员的结构体变量、结构体数组和结构体指针变量等。-36-9.5用用typedef定义类型定义类型(续)(续)【例【例9-12】自定义结构型举例。#includetypedefstructlongpersonID;charname10;doublesalary;PERSON;intmain()PERSONp1,p23;longpersonID;charname10;doublesalary;p1,p23;*/return0;-37-9.5用用typedef定义类型定义类
31、型(续)(续)4.自定义指针型自定义指针型可以利用自定义类型语句把某种类型的指针型定义为一个用户新类型。一般格式如下:typedef基本数据类型基本数据类型*用户新类型;用户新类型;功能:可用“用户新类型”定义“基本数据类型”的指针变量或数组。【例【例9-13】自定义指针类型举例。#includetypedefint*P1;typedefchar*P1;intmain()P1a,b;P2c,d;return0;-38-9.6程序设计举例程序设计举例【例【例9-14】结构体指针变量的使用。】结构体指针变量的使用。#includestructstuchar*name;intnum;charsex;
32、floatscore;*pstu,stu1=yanglan,1,F,92.5;intmain()pstu=&stu1;printf(Number=%d,Name=%sn,stu1.num,stu1.name);printf(Sex=%c,Score=%fnn,stu1.sex,stu1.score);printf(Number=%d,Name=%sn,(*pstu).num,(*pstu).name);printf(Sex=%c,Score=%fnn,(*pstu).sex,(*pstu).score);printf(Number=%d,Name=%sn,pstu-num,pstu-name)
33、;printf(Sex=%c,Score=%fn,pstu-sex,pstu-score);return0;-39-本章小结本章小结本章介绍了结构体、共用体及自定义数据类型。结构体是一种构造类型,它由若干个不同类型的成员组成,每个成员是一个基本数据类型或又是一个构造类型。结构体能较直观地反映问题域中数据之间的内在联系。结构体变量与普通变量一样,必须先定义后使用。可以分别引用结构体变量中的每一个成员,但不能整体引用结构体变量,这一点读者必须注意。也可以定义一个指针变量来指向结构体变量,这就是结构体指针变量。共用体数据类型是指在不同时刻在同一个内存单元存放不同类型的数据。共用体类型数据与结构体类型数据的区别在于:共用体类型各成员在不同时刻占用同一个内存区,内存区长度为各成员长度的最大值;结构体类型数据的每个成员各自占用不同的存储单元,所占空间为各个成员的长度之和。-40-谢 谢!
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100