18.1结构体类型的定义8.2结构体类型变量的定义和引用8.3结构体类型数组8.4指向结构体类型数据的指针第八章结构体和共用体8.5共用体类型8.6枚举类型8.7用户自定义类型2结构体类型的定义C语言的数据类型中有一种类型是“构造类型”,它是由若干个类型相同或不同的数据组合而成的,前面已经介绍过的数组就是一种构造类型,但是它只有存放数据类型相同的若干个数据,如果出现数据类型不同的若干个数据,用单个数组就无法将它们存放在一起,为了整体存放这些类型不同的相关数据,C语言提供了另一种构造类型:结构体类型,它可以将若干个不同类型的数据存放在一起。返回3一、结构体类型数据的特点构造类型是由相同或不同的数据类型组合而成。C语言规定用户可以自己定义一种数据类型来存放类型不同的数据。这种数据类型就称为“结构体类型”。例如,一个人的有关信息就是由不同数据类型的数据组合而成的,姓名是字符串型(用字符数组来存放),性别是字符型(用m表示男性,用f表示女性),年龄是整型,工资是实型,等等。这样就可以定义含有一个字符数组、一个字符型、一个整型、一个实型的数据为一个结构体类型数据。4又如一个学生的下列信息也可以定义为另一种结构体类型数据:学号姓名性别年龄成绩1成绩2成绩3长整型字符型字符整型实型实型实型这种结构体类型中可以定义成包含一个长整型、一个字符数组、一个字符型、一个整型、三个实型的结构体类型;也可以将其中的三个实型定义为一个实型数组。5二、结构体类型的定义格式:struct结构体类型名{数据类型1成员1名;数据类型2成员2名;...数据类型n成员n名;};注意:结构体定义语句的右花括号后面用“分号(;)”做语句结束标记。6结构体类型名是用户取的标识符;数据类型可以是基本类型说明符,也可以是已定义过的结构体类型名,还可以是后面要介绍的其他数据类型说明符,如共用体类型等。成员名是用户取的标识符,用来标识所包含的成员名称。成员也称“域”、“结构分量”。例如,为了存放一个人的姓名、性别、年龄、工资,可以定义如下的结构体类型:structperson{charname[20];charsex;intage;floatwage;};7又如,为了存放一个学生的学号、姓名、性别、年龄、成绩1、成绩2、成绩3,可以定义如下的结构体类型:structstudent{longnumber;charname[20];charsex;intage;floatscore[3];};结构体类型的定义是可以嵌套的,即某个结构体类型成员的数据类型可以说明为另一个已定义的结构类型。例如:8structbirthday{intyear;intmonth;intday;};structperson1{charname[20];charsex;structbirthdaybir;floatwage;};返回9结构体类型变量的定义和引用一、结构体类型变量的定义和初始化1、先定义结构体,后定义变量例如,为学生信息定义2个变量,程序段如下:structstudent{longnumber;charname[20];charsex;floatscore[3];};...structstudentx,y;10在定义变量的同时,可以对变量赋初值,例如上例中的定义语句可以改写如下:structstudentx={100001L,zhao1,'f',{89,94,86}},y={100002L,zhao2,'m',{78,86,92}};这个定义语句将使得变量x和y的各个成员获得如下的初值:numbernamesexscore[0]score[1]score[2]变量x100001Lzhao1'f'899486变量y100002Lzhao2'm'78869211例如,为学生信息定义2个变量x和y,并给它们赋初值,程序段如下:structstudent{longnumber;charname[20];charsex;floatscore[3];}x={100001L,zhao1,'f',{89,94,86}},y={100002L,zhao2,'m',{78,86,92}};2、定义结构体类型的同时定义变量123、定义无名称的结构体类型的同时定义变量例如,为学生信息定义2个变量x和y,并给它们赋初值,程序段如下:struct{longnumber;charname[20];charsex;floatscore[3];}x={100001L,zhao1,'f',{89,94,86}},y={100002L,zhao2,'m',{78,86,92}};13二、结构体类型变量成员的引用结构体类型变量成员的引用格式如下:结构体类型变量名.成员名其中的“·”称为成员运算符,其运算级别是最高的,和圆括号运算符“()”、下标运算符“[]”是同级别的,运算顺序是自左向右的。如果某个结构体类型变量的成员数据类型又是一个结构体类型,则其成员的引用方法如下:外层结构体类型变量.外层成员名.内层成员名1、结构体类型变量成员的引用方法14例1:我们以如下的学生信息结构体类型为例,给出其变量成员的引用方式。程序清单如下:#includestring.hstructstudent{longnumber;charname[20];charsex;floatscore[3];};15main(){structstudentx;x.number=100001L;strcpy(x.name,zhao1);x.sex='f';x.score[0]=89;x.score[1]=94;x.score[2]=86;printf(number=%ldname=%ssex=%c\n,x.number,x.name,x.sex);printf(score1=%fscore2=%f,x.score[0],x.score[1]);printf(score3=%f\n,x.score[2]);}16例2:用下面的嵌套的结构体类型为例,说明变量成员的引用。程序清单如下:#includestring.hstructbirthday{intyear;intmonth;intday;};structperson{charname[20];charsex;structbirthdaybir;floatwage;}x;17main(){strcpy(x.name,gu);x.sex='f';x.bir.year=1972;x.bir.month=10;x.bir.day=3;x.wage=2880.0;printf(name=%ssex=%cwage=%f\n,x.name,x.sex,x.wage);printf(birthday=%4d.%2d%2d\n,x.bir.year,x.bir.month,x.bir.day);}182、结构体类型变量成员地址的引用方法结构体类型变量成员地址的引用格式如下:&结构体类型变量名.成员名存放结构体类型变量成员地址的指针变量类型必须和该成员的类型相同。19例3以下面结构体类型为例,说明结构体类型变量成员地址的引用。程序清单如下:#includestring.hstructstudent2{longnumber;charname[20];}20main(){structstudent2x;long*p_number;char*p_name;p_number=&x.number;p_name=x.name;*p_number=100001L;strcpy(p_name,zhao1);printf(number=%dname=%s\n,*p_number,p_name);}213、结构体类型变量地址的引用方法结构体类型变量地址的引用格式如下:&结构体类型变量名存放结构体类型变量地址的指针变量必须是类型相同的结构体类型指针。返回22结构体类型数组如果数组的元素本身是一个结构体类型,则该数组称为结构体类型数组。一、结构体类型数组的定义和初始化1、先定义结构体类型,然后再定义结构体类型数组并赋初值。例如:structstudent{longnumber;charname[20];charsex;floatscore[3];};structstudents[3]={{200001L,qian2,'m',{78,86,92}},{200002L,sun3,'f',{85,69,82}},{200003L,li4,'m',{84,88,96}}};232、定义结构体类型的同时定义数组并赋初值例:structstudent{longnumber;charname[20];charsex;floatscore[3];}s[3]={{200001L,qian2,'m',{78,86,92}},{200002L,sun3,'f',{85,69,82}},{200003L,li4,'m',{84,88,96}}};243、定义无名称的结构体类型的同时定义数组并赋初值。例:struct{longnumber;charname[20];charsex;floatscore[3];}s[3]{{200001L,qian2,'m',{78,86,92}},{200002L,sun3,'f',{85,69,82}},{200003L,li4,'m',{84,88,96}}};25二、结构体类型数组元素成员的引用例:#includestring.hstructstudent2{longnumber;charname[20];}s[4];main(){s[0].number=100001L;strcpy(s[1].name,sun3);printf(%ld%s\n,s[0].number,s[1].name);}1、结构体类型数组元素成员的引用方法引用格式:结构体类型数组名[下标].成员名26例:下面以结构体类型数组s为例,说明其引用方法:#includestring.hstructstudent2{longnumber;charname[20];};2、结构体类型数组元素成员地址的引用方法引用格式:&结构体类型数组名[下标].成员名27main(){structstudent2s[2];long*p_number;char*p_name;p_number=&s[0].number;p_name=s[1].name;*p_number=100001L;strcpy(p_name,sun);printf(%ld,%s\n,s[0].number,s[1].name);}283、结构体类型数组元素地址的引用方法引用格式:结构体类型数组名[下标]返回4、结构体类型数组首地址的引用方法引用格式:结构体类型数组名29指向结构体类型数据的指针一、指向结构体类型变量的指针1、定义指向结构体类型变量的指针变量和定义结构体类型变量的方法基本相同,唯一的区别是在指针变量名的前面加一个指针标记*。2、当一个结构体类型变量的地址已赋予相同结构体类型的指针变量(即指针变量指向变量),就可以使用下列两种方式来引用该结构体类型变量的成员,其作用完全相同。方式1(*指针变量).成员名方式2指针变量-成员名30方式1比较好理解,其中“*指针变量”就代表了它所指向的结构体类型变量,利用“成员运算符”来引用,其作用相当于“结构体类型变量.成员名”。方式2是一种新的引用方法,其中的“-”称“指向成员运算符”,也简称“指向运算符”。其运算级别和“()”、“[]”、“.”是同级的。指向运算符的左边必须是已指向某个结构体类型变量或数组元素的指针变量,其右边必须是对应结构体类型数据的成员名。方式1(*指针变量).成员名方式2指针变量-成员名31例:使用指向结构体类型变量的指针变量处理如下结构体。程序清单如下:#includestring.hstructstudent2{longnumber;charname[20];}x,*p=&x;main(){p-number=100001L;strcpy(