《第九章结构体、联合体、枚举》由会员分享,可在线阅读,更多相关《第九章结构体、联合体、枚举(37页珍藏版)》请在金锄头文库上搜索。
1、结构体结构体数据类型C数据类型数据类型基本类型基本类型构造类型构造类型指针类型指针类型空类型空类型整整 型型浮浮 点点 型型字字 符符 型型枚举类型枚举类型单精度浮点型单精度浮点型双精度浮点型双精度浮点型数组类型数组类型结构体类型结构体类型联合体类型联合体类型结构体类型的定义结构体类型定义的一般形式为结构体类型定义的一般形式为: struct 结构体名结构体名 类型名类型名1 成员名成员名1; 类型名类型名n 成员名成员名n; ;struct是结构体类型的标志。是结构体类型的标志。结构体名结构体名是由是由用户定义的标识符,它规定了所定义的结构用户定义的标识符,它规定了所定义的结构体类型的名称。
2、结构体类型的组成成分称为体类型的名称。结构体类型的组成成分称为成员成员,成员名的命名规则与变量名相同。,成员名的命名规则与变量名相同。结构体类型的定义结构体类型定义形式结构体类型定义形式例如:例如: struct person char name20; char sex; int age; float height; ;表示定义了一个结构体类型表示定义了一个结构体类型struct person,它由它由name、sex、age和和height四个成员组成。四个成员组成。练习:定义一个结构体类型练习:定义一个结构体类型struct student,要求包含要求包含学生姓名、学号、数学成绩、英语成
3、绩、计算机成绩、学生姓名、学号、数学成绩、英语成绩、计算机成绩、总分、邮政编码、通讯地址。总分、邮政编码、通讯地址。结构体类型的定义在结构体类型定义中要注意以下几点:在结构体类型定义中要注意以下几点:结构体类型定义中可以包含另外的结构体,即结构结构体类型定义中可以包含另外的结构体,即结构体是可以嵌套的。例如:体是可以嵌套的。例如:struct date int year; int month; int day; ;struct person char name20; char sex; struct date birthday; float height; ;结构体类型变量一、结构体变量的定义
4、一、结构体变量的定义定定义义结结构构体体类类型型,只只是是说说明明了了该该类类型型的的组组成成情情况况,编编译译系系统统并并没没有有给给它它分分配配内内存存空空间间,就就象象系系统统不不为为int等等类类型型本本身身分分配配空空间间一一样样。只只有有当当定定义义属属于于结结构构体体类类型型的的变变量量时时,系系统才会分配存储空间给该变量。统才会分配存储空间给该变量。结构体类型变量一、结构体变量的定义一、结构体变量的定义1. 先定义结构体类型,再定义变量。例如:先定义结构体类型,再定义变量。例如:struct person char name20; char sex; int age; floa
5、t height; ; struct person per;表表示示先先定定义义了了结结构构体体类类型型struct person,然然后后定义了一个定义了一个struct person类型的结构体变量类型的结构体变量per。结构体类型变量一、结构体变量的定义一、结构体变量的定义结结构构体体变变量量占占用用的的内内存存空空间间是是其其成成员员所所占占内内存存之之和和,因因此此per 占占 用用 的的 内内 存存 空空 间间 为为20+1+4+4=27个个字字节节。结结构构体体变变量量中中的的各各成成员员在在内内存存中中按按定定义的顺序依次排列。义的顺序依次排列。注注意意:定定义义变变量量时时,
6、struct person必必须须在在一一起起使使用用,它它的的用用法法与与int、char等等类类型型名名的的用用法相同。法相同。成员名成员名所占空间所占空间(字节数)(字节数)nameheightagesex20144结构体类型变量二、结构体变量的引用二、结构体变量的引用(1)对结构体变量中成员的引用)对结构体变量中成员的引用引用的一般形式为:引用的一般形式为:结构体变量名结构体变量名.成员名成员名结构体类型变量(1)对对结结构构体体变变量中成员的引用量中成员的引用#include struct person char name20; char sex; struct data int y
7、ear; int month; int day; ; float height; ;void main() person per; data birthday;printf(Enter the name: );gets(per.name); per.sex=M;per.birthday.year=1982;per.birthday.year+;per.birthday.month=12;per.birthday.day=15;per.height=(175+176)/2;printf(%s%3c%4d/%2d/%d%7.1fn,per.name,per.sex, per.birthday.mo
8、nth, per.birthday.day, per.birthday.year, per.height);结构体数组一、结构体数组的定义一、结构体数组的定义定义结构体数组的方法和定义结构体数组的方法和定义结构体变量的方法一定义结构体变量的方法一样,只是必须说明其为数样,只是必须说明其为数组。例如:组。例如:struct person char name20; char sex; int age; float height; ; struct person per3;成员名成员名sexnameageheightsexnameageheightsexnameageheight数组元素数组元素pe
9、r0per1per2结构体数组一、结构体数组的定义一、结构体数组的定义定义结构体变量的三种方法都定义结构体变量的三种方法都可以用来定义结构体数组。例可以用来定义结构体数组。例如:如:struct person char name20; char sex; int age; float height; per3;struct char name20; char sex; int age; float height; per3;结构体数组二、结构体数组的初始化二、结构体数组的初始化和一般数组一样,结构体数组也可以进行初始化。和一般数组一样,结构体数组也可以进行初始化。struct person c
10、har name20; char sex; int age; float height; per3= LiPing,M,20,175,WangLing,W,19,162.5, Zhao Hui,M,20,178;数组每个元素的初值都放在一对大括号中,括号中依次排列数组每个元素的初值都放在一对大括号中,括号中依次排列元素各成员的初始值。元素各成员的初始值。与一般数组的初始化一样,如果给出了全部元素的初值,则与一般数组的初始化一样,如果给出了全部元素的初值,则数组的长度可以不指定,由系统根据初值的数目来确定数组数组的长度可以不指定,由系统根据初值的数目来确定数组长度。长度。结构体数组三、结构体数组
11、的引用三、结构体数组的引用对结构体数组的引用一般是对数组元素的成员进对结构体数组的引用一般是对数组元素的成员进行引用。引用只要遵循对行引用。引用只要遵循对数组元素的引用规则数组元素的引用规则和和对对结构体变量成员的引用规则结构体变量成员的引用规则即可。即可。程序功能:输出结构体数组各元素的成员值程序功能:输出结构体数组各元素的成员值void main()struct person char name20; char sex; int age; float height; per3= Li Ping,M,20,175, Wang Ling,F,19,162.5,Zhao Hui,M,20,178
12、;int i;for(i=0;i成员名 p-ID 结构体指针运算符“-” 结构体指针-结构体成员 struct struct personperson char name10 char name10; int int ageage; ; struct struct person *pperson *p,s s,boy3=boy3=”Zhang”, 18,”Wang”,20,”Li”,17;p=boyp=boy;对于已定义的结构体数组,若用一个变量来存放该结构体数组在内存中的首地址,则该变量为指向结构体数组的指针变量。例如,定义结构体类型person和结构体指针变量p。定义了结构体数组boy和结
13、构体指针变量p,且p指向数组boy的首地址。 结构体变量的首地址就是其指针,用取地址符得到指向结构体变量的指针变量称为结构变量的指针变量指向结构体变量的指针在使用时同样必须要先定义,再赋值,然后才可以使用如果有指针p 指向结构变量a,则 a.math 等价于 (*p).math 等价于 p-math使用指向结构数组的指针变量引用结构数组成员时,同指针指向数组时是类似的要明确指针当前指向的数组元素,同时要考虑结构体成员的引用方法联合体一、联合体类型及其变量的定义一、联合体类型及其变量的定义联合体类型定义的一般形式为:联合体类型定义的一般形式为: union 联合体名联合体名 类型名类型名1 成员
14、名成员名1; 类型名类型名n 成员名成员名n; ;union是联合体类型的标志。联合体名是由是联合体类型的标志。联合体名是由用户定义的标识符,它规定了所定义的联合用户定义的标识符,它规定了所定义的联合体类型的名称。联合体类型也由若干成员组体类型的名称。联合体类型也由若干成员组成。成。联合体一、联合体类型及其变量的定义一、联合体类型及其变量的定义union score char grade; float point; ;表示定义了一个联合体类型表示定义了一个联合体类型union score,它由它由grade和和point两个成员组成两个成员组成联合体一、联合体类型及其变量的定义一、联合体类型及
15、其变量的定义1. 先定义联合体类型,再定义变量。例如:先定义联合体类型,再定义变量。例如:union score char grade; float point; ;union score s;2. 定义类型的同时定义变量。:定义类型的同时定义变量。:union score char grade; float point; s;3.直接定义联合体类型直接定义联合体类型变量。变量。union char grade; float point; s;联合体一、联合体类型及其变量的定义一、联合体类型及其变量的定义联合体类型及其变量的定义在形联合体类型及其变量的定义在形式上与结构体很类似。但它们的式上与
16、结构体很类似。但它们的含义是不同的。含义是不同的。结构体变量的每结构体变量的每个成员分别占有独立的内存区域个成员分别占有独立的内存区域,因此结构体变量所占的内存字节因此结构体变量所占的内存字节数是其成员所占内存字节数之和。数是其成员所占内存字节数之和。而联合体变量的所有成员共同占而联合体变量的所有成员共同占用一段内存区域用一段内存区域,所以联合体变,所以联合体变量所占字节数是其成员中占内存量所占字节数是其成员中占内存空间最大的成员的字节数。空间最大的成员的字节数。gradepoint图图12.3联合体二、联合体变量的引用二、联合体变量的引用联合体变量也必须先定义,后使用。不能直联合体变量也必须
17、先定义,后使用。不能直接引用联合体变量,只能引用联合体变量的接引用联合体变量,只能引用联合体变量的成员。引用的一般形式为:成员。引用的一般形式为:联合体变量名联合体变量名.成员名成员名联合体变量的每个成员也可以像普通变量一联合体变量的每个成员也可以像普通变量一样进行其类型允许的各种操作。样进行其类型允许的各种操作。注意:注意:由于联合体类型采用的是覆盖技术,由于联合体类型采用的是覆盖技术,因此联合体变量中起作用的总是因此联合体变量中起作用的总是最后一次存最后一次存放放的成员变量的值。的成员变量的值。联合体二、联合体变量的引用二、联合体变量的引用程序功能:引用联合体变量的成员程序功能:引用联合体
18、变量的成员#include void main() union temp char a; int b; t; t.a=66; t.b=266; /*266=256+10即即266的二进制为的二进制为1 00001010,所,所以高字节放以高字节放1、低字节放、低字节放10*/ printf(%x:%d , %x:%dn,&t.a , t.a ,&t.b , t.b);变量变量t起始地址起始地址联合体xxxxxxxx xxxxxxxx成员变量成员变量a赋值前赋值前01000010 xxxxxxxx成员变量成员变量a赋值后赋值后变量变量t起始地址起始地址01000010 xxxxxxxx成员变量成
19、员变量b赋值前赋值前变量变量t起始地址起始地址00001010 00000001成员变量成员变量b赋值后赋值后变量变量t起始地址起始地址联合体联合体变量可以作为结构体联合体变量可以作为结构体变量的成员,结构体变量也变量的成员,结构体变量也可以作为联合体变量的成员,可以作为联合体变量的成员,并且联合体类型也可以定义并且联合体类型也可以定义数组。数组。程序功能:联合体变量作为程序功能:联合体变量作为结构体变量的成员结构体变量的成员注意:注意:不能对联合体变量进不能对联合体变量进行初始化。不能将联合体变行初始化。不能将联合体变量作为函数参数和返回值。量作为函数参数和返回值。 struct stude
20、nt char *name; int dept; union score char grade; float point; s; stu2;枚举类型一、枚举类型及其变量的定义一、枚举类型及其变量的定义枚举类型定义的一般形式为:枚举类型定义的一般形式为: enum 枚举名枚举名 枚举元素枚举元素1,枚举元素,枚举元素2,;enum是枚举类型的标志。枚举名是由用户是枚举类型的标志。枚举名是由用户定义的标识符,它规定了所定义的枚举类型定义的标识符,它规定了所定义的枚举类型的名称的名称,例如:例如: enum season spring, summer, autumn, winter;表示定义了一个枚
21、举类型表示定义了一个枚举类型enum season,它包含四个枚举元素。它包含四个枚举元素。枚举类型一、枚举类型及其变量的定义一、枚举类型及其变量的定义定义了枚举类型后,就可以用它定义枚举类型定义了枚举类型后,就可以用它定义枚举类型变量。枚举类型变量的定义有两种方法。变量。枚举类型变量的定义有两种方法。1. 先定义枚举类型,再定义变量。例如:先定义枚举类型,再定义变量。例如: enum season spring, summer, autumn, winter ; enum season s;表示定义了一个表示定义了一个enum season枚举类型和属于枚举类型和属于该类型的变量该类型的变量
22、s。2. 直接定义枚举变量。例如:直接定义枚举变量。例如:enum spring, summer, autumn, winter s;枚举类型一、枚举类型及其变量的定义说明一、枚举类型及其变量的定义说明(1)枚举类型中的枚举元素是用户定义的标识)枚举类型中的枚举元素是用户定义的标识符,对程序来说,这些标识符并不自动代表符,对程序来说,这些标识符并不自动代表什么含义。例如,写成什么含义。例如,写成spring并不自动表示为并不自动表示为“春季春季”,写成,写成spr也可以。也可以。(2)在)在C 编译中,将枚举元素作为常量处理,编译中,将枚举元素作为常量处理,称为枚举常量。因此不能对它们进行赋值
23、。称为枚举常量。因此不能对它们进行赋值。例如:例如: spring=0; winter=1;是不合法的。是不合法的。 枚举类型一、枚举类型及其变量的定义说明一、枚举类型及其变量的定义说明(3)枚举元素是被处理成一个整型常量的,它的值取)枚举元素是被处理成一个整型常量的,它的值取决于定义时各枚举元素决于定义时各枚举元素排列的先后顺序排列的先后顺序。第一个枚举。第一个枚举元素的值为元素的值为0,第二个为,第二个为1,依次顺序加,依次顺序加1。 例如,在以上的定义中,例如,在以上的定义中,spring的值为的值为0,summer的值为的值为1,autumn的值为的值为2,winter的值则为的值则为
24、3。也可以也可以在定义时改变枚举元素的值在定义时改变枚举元素的值。例如:。例如: enum spring=1, summer, autumn, winter=0 s;没有指定值的枚举元素,其值为前一元素值加没有指定值的枚举元素,其值为前一元素值加1。因。因此,此,spring的值为的值为1,summer的值为的值为2,autumn的值的值为为3,而,而winter的值为的值为0。枚举类型二、枚举类型变量的基本操作二、枚举类型变量的基本操作1. 枚举变量的赋值枚举变量的赋值只能给枚举变量赋枚举常量。不能直接给枚举变量赋只能给枚举变量赋枚举常量。不能直接给枚举变量赋整型值,但是可以通过将整型值强制
25、类型转换成枚举整型值,但是可以通过将整型值强制类型转换成枚举类型赋值。类型赋值。程序功能:为枚举类型变量赋值程序功能:为枚举类型变量赋值void main() enum season spring, summer, autumn, winter s1,s2 ; s1=summer; s2=(enum season)2; printf(s1=%d,s2=%dn,s1,s2); 枚举类型二、枚举类型变量的基本操作二、枚举类型变量的基本操作2.枚举元素的判断比较枚举元素的判断比较void main() enum season spring=1, summer, autumn, winter s ;
26、for (s=spring;s=winter;s+) printf(%d ,s); 枚举类型二、枚举类型变量的基本操作二、枚举类型变量的基本操作3. 枚举变量只能通过赋值语句得到值,枚举变量只能通过赋值语句得到值,不能通过输入不能通过输入语句直接输入数据。也不能使用输出语句直接输出语句直接输入数据。也不能使用输出语句直接输出枚举元素枚举元素,可以通过,可以通过switch语句将枚举元素以字符串语句将枚举元素以字符串形式输出。形式输出。 switch(s) case spring: printf(springn); break; case summer: printf(summern); bre
27、ak; case autumn: printf(autumnn); break; case winter: printf(wintern); break; 类型定义typedef定义新类型名的一般形式是: typedef 类型名 标识符使用typedef语句不是创造新类型,而是为已经存在的类型增加了一个名字。例如: struct person char name20; char sex; int age; ; typedef struct person PERSON; PERSON per3;用途:可以增加程序的可读性/*- 程序功能:统计学生人数 计算平均成绩 -*/ #include vo
28、id main() struct student char name20; char sex; int score; ; struct student stu5; int i,m_num=0,f_num=0; float average,sum=0; for(i=0;i5;i+) printf(Please input name :); gets(stui.name); printf( sex :); scanf(%c,&stui.sex); printf( score:); scanf(%d,&stui.score); getchar(); for(i=0;i5;i+) if (stui.s
29、ex=M|stui.sex=m) m_num=m_num+1; else f_num=f_num+1; sum=sum+stui.score; average=sum/5; printf(m_num=%d, f_num=%d, average=%7.2fn, m_num,f_num,average); 1. 定义一个包括年、月、日的结构体变量,当输入年、定义一个包括年、月、日的结构体变量,当输入年、 月、日数据后,计算该日是这一年中的第几天。月、日数据后,计算该日是这一年中的第几天。 2.从键盘输入从键盘输入10个学生的数据,包括个学生的数据,包括:学号、姓名、三门学号、姓名、三门 课的成绩。
30、要求输出三门课总平均课的成绩。要求输出三门课总平均 成绩,及最高分学成绩,及最高分学 生的数据(学号、姓名、三门课成绩、平均分数)。生的数据(学号、姓名、三门课成绩、平均分数)。 3.从键盘输入从键盘输入5个用户的数据,包括:姓名和电话号码个用户的数据,包括:姓名和电话号码 要求按姓名排序后,输出用户的全部数据。要求按姓名排序后,输出用户的全部数据。 4.定义一种类型定义一种类型stu可以放学生的姓名、学号、英语成绩可以放学生的姓名、学号、英语成绩 其其中中英英语语成成绩绩有有的的老老师师按按照照“优优”、“良良”、“中中”、“及格及格” “不及格不及格”五个等级给的,有的老师按照百分制给的成五个等级给的,有的老师按照百分制给的成 绩,要求该类型可以如实反映学生的情况。绩,要求该类型可以如实反映学生的情况。 5.定义一个枚举变量,其枚举元素为人民币的面值。要定义一个枚举变量,其枚举元素为人民币的面值。要 求输出枚举元素字符串。求输出枚举元素字符串。 6.使用结构体类型,修改使用结构体类型,修改“学生成绩管理系统学生成绩管理系统”。