第08章.结构体和枚举类型.ppt

上传人:sccc 文档编号:4875114 上传时间:2023-05-20 格式:PPT 页数:92 大小:309.51KB
返回 下载 相关 举报
第08章.结构体和枚举类型.ppt_第1页
第1页 / 共92页
第08章.结构体和枚举类型.ppt_第2页
第2页 / 共92页
第08章.结构体和枚举类型.ppt_第3页
第3页 / 共92页
第08章.结构体和枚举类型.ppt_第4页
第4页 / 共92页
第08章.结构体和枚举类型.ppt_第5页
第5页 / 共92页
点击查看更多>>
资源描述

《第08章.结构体和枚举类型.ppt》由会员分享,可在线阅读,更多相关《第08章.结构体和枚举类型.ppt(92页珍藏版)》请在三一办公上搜索。

1、第8章结构体和枚举类型,本章要点:,教学目标本章讲解结构和结构变量的定义格式、结构成员的表示、结构变量的赋初值和赋值、结构变量的运算。在此基础上进一步讲述结构与指针、结构与数组、结构与函数的应用。教学重点和难点 结构体类型的定义 定义和初始化结构体变量 类型定义typedef 结构体数组 结构体指针 结构体与函数 单向链表及其操作 枚举类型,在现实生活中,有许多不同性质的数据实体。比如,通讯录通常由姓名、电话、E-mail、年龄等组成。姓名、电话、E-mail和所在城市可以用字符串表示,年龄可以用整型数表示。可是它们的每一项都是单独使用的,不能反映通讯录这样一个整体。用什么方法表示通讯录这个整

2、体呢?新的被称为结构体的数据类型。为我们处理复杂的数据提供了便利的手段。,8.1.1 什么是结构体结构体(structure)是一种数据类型,它把互相联系的数据组合成一个整体。例如,下面的表格显示了一个通讯录的信息:表8-1 一个通讯录的信息表一个通讯录中有姓名、电话、性别、年龄、E-mail地址、所在城市,这些信息都是和一个叫“李明”的人有关。如果我们只把这些信息分别定义为独立的简单变量,就体现不出它们之间的相互关联了。所以,应当把它们组织成一个组合项,在一个组合项中包含若干个类型不同的数据项。用“结构体”来定义。,8.1 结构体类型,8.1.2 结构体的定义结构体既然是一种数据类型,在使用

3、前,先要“定义”出要使用的结构体类型。例:将通讯录定义成一个结构体。通讯录的信息由六项属性组成,首先要给这个结构体类型定义取一个名字,比如“AddressList”。然后,应该在结构体定义中对各属性进行说明。下面就是“通讯录”结构体类型:struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/;,8.1 结构体类型,其中,“struct”是关键字,是结构体的标识符,不能省略。“AddressLis

4、t”是结构体类型名,它由我们自己进行命名的。“”中是结构体的成员,每个成员的数据类型既可以是简单的数据类型,也可以是复杂的数据类型,当然也可以是其他结构体数据类型。最后,定义完一个结构体后一定要用一个分号“;”结束。从上面这个例子,可以看出结构体定义格式如下:,8.1 结构体类型,struct 名字 成员说明1;成员说明2;成员说明3;成员说明n;;,可以定义许多复杂的数据类型。比如,定义一个表示日期的结构体:struct dateint year;/*年*/int month;/*月*/int day;/*日*/;用日期这种结构体,我们就可以表示生日、开学时间、春节等等这样的日期。,8.1

5、结构体类型,也可把两种结构体类型结合起来,“造出”更复杂的结构体。比如,一个通讯录的结构体中包含了表示出生日期的结构体struct date:struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/struct date birthday;/*出生日期*/;,8.1 结构体类型,我们先“造出”一个日期的结构体类型,同时我们又在通讯录这个结构体中,将出生日期这个成员变量定义为日期类型,这样通讯录结构

6、体就变成更复杂一些的数据类型了。这样的结构可以叫做嵌套型的结构体,其结构可以如图8-1示意:图8-1 嵌套型的结构体示意,8.1 结构体类型,8.1.3 定义结构体变量既然我们定义的结构体是一种数据类型,就可以像int、char、float这样的数据类型一样来使用,定义结构体类型的变量。用结构体类型定义变量的方式有如下几种:1.先定义结构体类型,再定义变量例,定义一个通讯录结构体:struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件

7、*/char addr30;/*地址*/;/*定义2个结构体变量*/struct AddressList AddressList1,AddressList2;,8.1 结构体类型,定义了两个“AddressList”结构体类型的变量AddressList1和AddressList2。它们可以分别表示两个人的通讯录,比如:AddressList1:AddressList2:图8-2 结构体变量,8.1 结构体类型,结构体变量中的各个成员,在内存中是顺序存放的。各成员变量所占内存的大小是根据定义时它们的数据类型来决定。为了方便,也可以这样定义结构体变量:#define ADDRESSLIST st

8、ruct AddressListADDRESSLISTchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/;ADDRESSLIST AddressList1,AddressList2;,8.1 结构体类型,定义的这个符号常量“ADDRESSLIST”,它就代表了结构体类型“struct AddressList”。这样,在未来的程序设计中,“ADDRESSLIST”可以和“struct AddressList”完全等效使用了。2.

9、在定义结构体类型的同时声明变量struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/AddressList1,AddressList2;,8.1 结构体类型,这种方式和前面定义的方式效果一样,在定义结构体的同时,定义了2个struct AddressList类型的变量AddressList1,AddressList2。这种方式通常用于函数中使用的局部结构体变量。3.直接定义变量还可以用下面的方式

10、直接定义结构体变量:struct/*省略结构体名称*/char name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/AddressList1,AddressList2;,8.1 结构体类型,这种方式没有给出结构体名,通常也用于函数中使用的局部结构体变量。注意:1)对于结构体变量,在定义时,一定要先定义一个结构体类型,然后再定义该类型的变量。只能对结构体变量赋值、存取或运算,但不能对一个结构体类型进行这些操作;2)对结构体中的组成成员,可以

11、单独使用,它的作用相当于普通变量。4.类型定义typedef在编写程序的过程中,为了便于修改和表达清晰,我们往往还可以给数据类型取别名,在C+语言中叫做类型定义。类型定义的关键字是typedef,其使用格式为:,8.1 结构体类型,typedef 数据类型标识符 别名;,比如我们给整型标识符int取个别名,叫做Integer,可以这样写:typedef int Integer;Integer k;这样定义的变量k就是一个整型数。,8.1 结构体类型,同样可以对一个结构体进行类型定义,也就是给这个结构体取个别名。比如给前面定义的通讯录取个别名,并用别名定义变量:typedef struct Ad

12、dressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/ADDR_LIST;/*定义2个struct AddressList类型的变量*/ADDR_LIST AddressList1,AddressList2;,或者:struct AddressListtypedef struct AddressList ADDR_LIST;也可省略结构体的名称AddressList,写成如下的形式:typedef structA

13、DDR_LIST;,8.1 结构体类型,8.1.4 结构体变量的初始化1.结构体整体初始化声明一个结构体变量时,可以对它进行初始化,这和初始化一个数组是类似的。结合上面定义的通讯录结构体类型struct AddressList,我们定义了一个struct AddressList变量one,并对它进行初始化:struct AddressList one=李明,01062548445,M,16,北京;,8.1 结构体类型,注意:不能在定义结构体类型的时候,进行赋初值。例如:struct AddressList/*下面的做法就是错误的*/char name=Li Lin;char telephone

14、12=010-62281234;char sex=M;int age=18;char e_mail40=;char addr30=123 Bejing Road;one;,例8.1 定义一个结构体变量,并进行整体初始化,再输出其结果内容。程序清单 C08_01.cpp#include/*结构体定义部分*/struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/;,8.1 结构体类型,void ma

15、in()/*定义并初始化结构体变量*/struct AddressList one=李明,01062548445,M,16,北京;/*结构体变量的输出*/cout 我们定义并初始化的结构体是:n endl;cout 姓名是:one.name endl 电话号码是:one.telephone endl;cout 性别是:one.sex endlcout 所在城市是:one.addr endl;,8.1 结构体类型,输出结果:我们定义并初始化的结构体是:姓名是:李明电话号码是:01062548445性别是:M年龄是:16E-mail地址是:所在城市是:北京其中的“one.name”、“one.te

16、lephone”是通过“.”运算符访问结构体变量的成员。一般情况下,不能将一个结构体变量作为整体来使用,只能使用其中的成员(分量)。使用结构体成员的方式:,8.1 结构体类型,结构体变量名.成员名,通过这种方式,我们就可以使用结构体变量one中的成员了。例:cout one.name,one.telephone,one.sex,one.age,one.e_mail,one.addr;注意,成员“.”操作符左边必须是结构体变量名,右边必须是结构体中已定义的成员名。下面这些写法都是错误的:strcpy(AddressList.name,wangli);/*AddressList是结构体类型名,不是

17、结构体变量*/one.book=6;/*结构体AddressList中没有定义“book”这个成员*/,8.1 结构体类型,2.初始化结构体部分成员既然,结构体变量的成员可以通过“.”操作符来访问,我们就可以使用赋值语句对它们进行初始化了。例如,对于上面例8.1,对变量one的初始化,还可以使用赋值语句完成:strcpy(one.name,李明);strcpy(one.telephone,01062548445);one.sex=M;one.age=16;strcpy(one.e_mail,);strcpy(one.addr,北京);使用这种方式,比起第一种初始化方式要灵活一下,一般适用于对结

18、构体的某个成员变量进行设置时使用。当然,使用输入语句也可以实现部分结构体成员的初始化。例如:cin one.age;,8.1 结构体类型,3.逐级访问成员在前面曾经定义了包含生日的通讯录结构体,生日这个成员变量又是日期结构体类型。对于生日这个成员变量,我们可以一级一级访问其成员。例如:AddressList1.birthday.month=9;AddressList1.birthday.day=20;AddressList1.birthday.year=1994;,8.1 结构体类型,4.把结构体变量当作整体赋值只有在以下两种情况下,才可以把结构体变量作为一个整体来赋值和访问。1)结构体变量整

19、体赋值例:AddressList2=AddressList1;通过这种模式,可以直接完成结构体之间的赋值。2)取结构体变量地址例如:cout AddressList1.telephone;/*输入AddressList1的电话*/需要注意,不能把结构体变量整体输入进来。例如:cin AddressList1;我们在使用结构体变量时,通常把结构体变量的地址用作函数的参数,以实现传地址调用。,8.1 结构体类型,8.1.5 结构体数组我们知道,一个结构体变量可以存放一组相关的数据(例如,一个通讯录可以存放一个人的姓名、电话、性别、年龄、E-mail和地址等信息),正如前面引入数组一样,我们也可以定

20、义一个数组,其每一成员都是一个结构体,它们都分别包含多个成员变量。1.结构体数组的定义我们在定义结构体数组之前,首先要进行结构体类型的定义。然后再像以前介绍过的数组定义方式定义结构体数组。,8.1 结构体类型,例如,我们定义一个具有3个元素的通讯录结构体数组:/*定义结构体类型*/typedef struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/ADDR_LIST;/*定义结构体数组*/AD

21、DR_LIST addlist3;/*定义有3个元素的结构体数组*/这样就定义了一个具有3个元素的结构体数组,这些数组元素在内存中是连续存放的。,8.1 结构体类型,2.结构体数组的初始化我们可以把结构体初始化和数组元素初始化结合起来,对结构体数组进行初始化。经过初始化,就可以分别输出结构体数组元素的值。例8.2 结构体数组的初始化。程序清单 C08_02.cpp#include typedef struct char name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/c

22、har addr30;/*地址*/ADDR_LIST;,8.1 结构体类型,void Print(ADDR_LIST*,int Count);void main()/*定义并初始化结构体变量*/ADDR_LIST addrlist3=李明,01062548445,M,16,北京,王芳,02162281234,F,20,上海,Marry,02786614571,F,19,武汉,;Print(addrlist,3);,8.1 结构体类型,void Print(ADDR_LIST*List,int Count)int i;/*结构体变量的输出*/cout 我们定义并初始化的结构体数组的数据如下:nn

23、;for(i=0;i Count;i+)cout 第 i+1 个记录:endl;cout 姓名:Listi.name endl;cout 电话号码:Listi.telephone endl;cout 性别:Listi.sex endl;cout 年龄:Listi.age endl;cout E-mail:Listi.e_mail endl;cout 所在城市:Listi.addr endl;cout endl;,8.1 结构体类型,输出结果我们定义并初始化的结构体数组的数据如下:第1个记录:姓名:李明电话号码:01062548445 性别:M 年龄:16 E-mail:所在城市:北京第2个记录

24、:姓名:王芳电话号码:02162281234 性别:F 年龄:20 E-mail:所在城市:上海,8.1 结构体类型,第3个记录:姓名:Marry电话号码:02786614571 性别:F 年龄:19 E-mail:所在城市:武汉,8.1 结构体类型,8.1.6 结构体指针结构体指针,就是一个结构体类型的指针,它指向一个结构体变量。这和整型指针、字符指针是一样的。其实例8.2的Print函数中就使用了结构体指针作为形参(*List)。1.结构体指针我们再看一个应用结构体指针的小例子。例8.3 我们定义一个表示某人生日的结构体变量,同时定义一个结构体指针指向它,分别通过结构体变量和结构体指针输出

25、结构体成员的值,观察其结果的不同。,8.1 结构体类型,程序清单 C08_03.cpp/*结构体变量和结构体指针的关系*/#include/*结构体类型定义,其中结构体date是结构体PERSON的成员变量*/struct dateint month;/*表示月,从112*/int day;/*表示日期,从131*/int year;/*表示年*/;/*定义结构体类型,并且是复合(成员变量是结构体类型)类型*/typedef structint No;/*序号*/char name20;/*姓名*/struct date birthday;/*出生日期*/PERSON;,8.1 结构体类型,v

26、oid main()PERSON Users;/*定义Users是一个结构体变量*/PERSON*p;/*定义*p是一个结构体指针*/cout Users.No;/*Users.No是整型变量*/cout Users.name;/*Users.name字符数组的名字,其表示地址*/cout Users.birthday.year Users.birthday.month Users.birthday.day;p=cout 序号:Users.No endl,8.1 结构体类型,姓名:Users.name endl 生日:Users.birthday.year Users.birthday.mon

27、th Users.birthday.day endl;cout n通过结构体指针变量输出的结果:n;cout 序号:(*p).No endl 姓名:(*p).name endl 生日:(*p).birthday.year(*p).birthday.month(*p).birthday.day endl;,8.1 结构体类型,输出结果请输入结构体变量的信息:请输入序号:010姓名:Jordan请输入生日日期(YYYY-MM-DD):1973-3-23通过结构体变量输出的结果是:序号:10姓名:Jordan生日:1973-3-23通过结构体指针变量输出的结果:序号:10姓名:Jordan生日:19

28、73-3-23,8.1 结构体类型,可见,通过结构体变量和结构体指针变量输出的结果完全一样。在程序中我们定义了一个结构体类型PERSON,然后在主函数定义了一个PERSON类型变量Users。与此同时,定义了一个结构体PERSON指针变量p,并让它指向Users。情况如图8-3所示。,8.1 结构体类型,图8-3 结构体变量和结构体指针的关系,8.1 结构体类型,这样,结构体变量Users和结构体指针p就表示同一部分数据。从源程序中我们可以看出,对于指针类型的结构体变量的成员,我们使用“(*p).No”、“(*p).name”这样的形式访问。其中,“(*p)”表示p指向的结构体变量Users,

29、“(*p).No”就是p指向的结构体变量中的成员No。注意,“*p”两侧的括弧可不能省!因为运算符“.”的优先级要高于指针运算符“*”,如果省略括弧,“*p.No”就表示了“p.No”是指针了(等价于“*(p.No)”),它和“(*p).No”不是一回事。,8.1 结构体类型,可以把“(*p).No”改用指向运算符“-”表示为“p-No”。同样,“(*p).name”也等价于“p-name”。因此,下面三种形式是等价的:Users.成员名(*p).成员名p-成员名有了这些规则,我们可以把上面“通过结构体指针变量输出”的语句改为:printf(序号是:%dn姓名是:%sn生日是:%d-%d-%d

30、n,p-No,p-name,p-birthday.month,p-birthday.day,p-birthday.year);其中“-”称为指向运算符。,8.1 结构体类型,2.指向结构体数组的指针指针和数组之间的关系十分密切:如果指针p指向数组的某个特定元素,那么p+1就指向该数组中下一个元素,p+i指向该元素后面第i个元素,p-i指向该元素之前第i个元素。同样,对结构体数组及其元素也可以用指针变量来指向。例,我们在例8.2中定义了一个结构体数组,并进行了初始化。现在我们用指向结构体数组的指针进行操作,结果会是怎么样呢?例8.4 定义一个结构体数组变量,进行数组元素的整体初始化,并利用指向结

31、构体数组的指针输出结构体的数据。,8.1 结构体类型,程序清单 C08_04.cpp#include/*结构体定义部分*/struct AddressListchar name20;/*姓名*/char telephone12;/*电话*/char sex;/*性别*/int age;/*年龄*/char e_mail40;/*电子邮件*/char addr30;/*地址*/;typedef struct AddressList ADDR_LIST;/*将此结构体类型定义为ADDR_LIST*/,8.1 结构体类型,void main()/*定义并初始化结构体变量*/ADDR_LIST Lis

32、t3=李明,01062548445,M,16,北京,王芳,02162281234,F,20,上海,Marry,02786614571,F,19,武汉,;ADDR_LIST*p;/*定义一个指向结构体类型的指针*/*结构体变量的输出*/cout name telephone sex age endl;,8.1 结构体类型,cout e_mail addr endl;输出结果用指向结构体数组的指针输出的结构体变量值是:姓名:李明电话号码:01062548445 性别:M 年龄:16 e_mail:所在城市:北京,8.1 结构体类型,姓名:王芳电话号码:02162281234 性别:F 年龄:20

33、e_mail:所在城市:上海 姓名:Marry电话号码:02786614571 性别:F 年龄:19 e_mail:所在城市:武汉,8.1 结构体类型,输出结果和例8.2的一样。我们在程序中定义了指向ADDR_LIST结构体数组List的指针p,在for语句中先赋值p的初值为List,即结构体数组的起始地址,如图8-4所示。在第一次循环中,输出List0的各成员值,然后执行p+,使p指向List1的起始地址。同样,第二次循环后,p指向List2的起始地址。再执行p+后,p的值为List+3,循环条件不满足,于是退出循环。,8.1 结构体类型,图8-4 指向结构体数组的指针,8.1 结构体类型,

34、我们在使用指向结构体数组指针时需要注意以下几点:1)(+p)和(p+)是不同的。例如:“(+p)-telephone”先使p自加1,然后得到它指向的元素中的telephone成员值,即“List1.telephone(02162281234)”。“(p+)-telephone”先得到“p-telephone”的值,即01062548445,然后再p自加1,即指向List1。2)如果定义p是结构体类型ADDR_LIST的指针,它只能指向一个此结构体类型的变量。例如,下面这样描述是错误的:p=/*错误*/,8.1 结构体类型,8.1.7 结构体与函数有时,我们想把一个结构体变量的值传递给另一个函数

35、,用什么方法呢?可以利用前面学过函数的传值调用,既可以传递单个结构体成员也可以传递整个结构体。例如:用List0.name或List0.telephone作函数的实参,通过函数调用将实参值传递给形参。这种用法和用普通变量作实参没有任何区别,都是“值传递”方式,被调用函数无法修改主调函数中的结构体变量成员。如果我们需要被调用函数能改变主调函数中结构体变量成员,该用什么方法呢?通过指针的学习,自然使我们想到可以用指向结构体变量的指针作实参,或将结构体变量的地址作为实参调用函数。比起传值调用,传地址方式不需要对整个结构体做一份拷贝,只需要把结构体变量的地址传递给函数就可以了。,8.1 结构体类型,图

36、 8-5 回顾:传值和传地址调用的比较示意,8.1 结构体类型,先让我们看一看指针指向结构体变量的小例子!例8.5 用结构体变量的地址作为实参调用函数。定义一个结构体包括学生的学号、姓名和三门主课(数学、语文、英语)的成绩和平均分。在主函数main定义此结构体变量Exam,调用函数GetInfo()输入赋值到Exam,再调用函数Comp()计算平均分并输出。程序清单 C08_05.cpp#include typedef structint math;/*数学成绩*/int chinese;/*语文成绩*/int english;/*英语成绩*/SCORE;,8.1 结构体类型,typedef

37、structint No;/*学号*/char Name20;/*姓名*/SCORE Score;/*三门成绩*/int Average_score;/*平均分*/Information;/*函数声明部分*/void GetInfo(Information*p);/*从键盘输入数据*/void Comp(Information*p);/*计算平均分*/void main()Information Exam;/*定义一个学生信息的结构体变量*/GetInfo(/*用地址作为参数*/,8.1 结构体类型,void GetInfo(Information*p)/*形参采用指针类型*/cout p-N

38、o;cout p-Name;cout Name p-Score.math p-Score.chinese p-Score.english;void Comp(Information*p)/*形参采用指针类型*/p-Average_score=(p-Score.math+p-Score.chinese+p-Score.english)/3;,8.1 结构体类型,cout Name No Score.math Score.chinese Score.english Average_score Average_score)=85)cout 成绩优秀!n;elsecout 成绩一般!n;,8.1 结构

39、体类型,输出结果请输入一位学生的信息:学号:010姓名:JordanJordan的三门主课成绩(数学,语文,英语)是:98,76,97调用函数Comp()计算Jordan的平均成绩如下:学号:10数学:98,语文:76,英语:97三门功课平均成绩:90成绩优秀!,8.1 结构体类型,这里,输入函数GetInfo(),计算函数Comp()的形参都是结构体Information类型的指针。在调用它们的时候,使用Information类型变量Exam的地址,这样在函数中对形参的修改就是直接对实参的修改。图8-6(a)是调用函数GetInfo()或者Comp()后的实参和形参的关系。(a)函数形参是结

40、构体指针,实参是结构体变量地址,调用后,指针指向实参的结构体,8.1 结构体类型,(b)例8.5中的两个函数GetInfo()、Comp()处理的数据都是主函数中定义的Exam图8-6 函数形参是结构体指针,实参是结构体变量地址,8.1 结构体类型,在C+语言中,允许将整个结构体作为函数的参数进行传递,当然必须保证函数的形参和实参类型必须相同。但这种方法,程序运行时需要将全部成员一个一个传递给函数,又费时、又浪费空间,开销太大。如果结构体类型中成员很多,比如一个大的结构体,这种情况下,还是使用结构体指针进行函数参数传递,效率要更高。下面我们用传递结构体变量和传递结构体指针的方法修改,并输入一个

41、结构体变量,从中体会不同的参数传递方式的差异。例8.6 定义一个日期结构体类型,并定义一个日期结构体变量,对其初始化。编写两个函数,一个的形参是日期结构体类型,一个的形参是日期结构体指针类型。两个函数中都先对形参修改,然后输出。,8.1 结构体类型,程序清单 C08_06.cpp#include/*结构体定义部分*/typedef structint year;/*年*/int month;/*月*/int day;/*日*/DATE;,8.1 结构体类型,/*函数定义*/void Mp1(DATE OneDay)OneDay.year=1999;void Mp2(DATE*pOneDay)p

42、OneDay-year=2050;void main()DATE OneDay=2002,10,1;/*定义一个结构体DATE类型变量,并初始化*/DATE*p=,8.1 结构体类型,Mp1(OneDay);cout year month day;cout endl;输出结果日期结构体变量原始值:2002-10-1调用传值函数Mp1(DATE OneDay)的结果:2002-10-1调用传指针函数Mp2(DATE*pOneDay)的结果:2050-10-1,8.1 结构体类型,通过上面这段程序,我们可以看到,调用Mp1()不会影响实参值,而调用Mp2()就会影响实参值,我们从中可以再次体会到传

43、值和传地址调用的不同。下面用图8-7示意这个实例的参数传递情况。,8.1 结构体类型,图8-7 例8.7中的调用函数Mp1()、Mp2()参数传递情况,8.1 结构体类型,在实际生活中,我们常常遇到这样一些情况:交通灯只有红、黄、绿三种颜色;一个星期有七天;一年有十二个月;一个小组有张三、李四等。这些变量的取值被限定在一个有限的范围内,如果把这些量说明为整型、字符型或其他类型显然都不合适。为此,语言提供了一种称为“枚举”的类型。所谓“枚举”是指将变量的值一一列举出来,变量的值只限于列举出来的值范围内。这样,被说明为该“枚举”类型的变量取值就不能超过定义的范围了。需要说明的是,枚举类型是一种基本

44、数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。在定义结构体的时候,我们也可以应用枚举类型。,8.2 枚举类型,8.2.1 枚举类型的定义枚举类型和其他基本数据类型一样,在使用它声明变量之前,必须先定义枚举类型。定义枚举类型定义的格式为:枚举类型的定义语句的关键字是enum。用户定义的枚举类型名,它是一个标识符,表示一个新的枚举类型。花括号括起来的是该类型定义体,其中的内容又称为枚举表。枚举表是一组由用户命名的符号常量,它们用逗号分开,每个符号常量又称为枚举常量或枚举值。枚举表内的值确定了枚举类型变量的取值范围。例如,我们定义:enum color red,yellow,gree

45、n;enum day Sun,Mon,Tues,Wed,Thur,Fri,Sat;,8.2 枚举类型,enum 枚举类型名 枚举表;,其中,red、yellow、green,Sun、MonSat称为“枚举元素”或“枚举常量”。第一条语句定义了一个枚举类型color,用来表示交通灯的颜色,它的取值范围是三个枚举值red、yellow和green,分别代表红色、黄色和绿色。第二条语句定义了一个枚举类型day,用来表示日期,它包含7个枚举值,分别表示星期日、星期一至星期六。另外枚举表中的元素都是常量,它们规定了枚举变量的取值范围。数组可就不同了,数组的元素可以是基本类型、或者用户自定义的数据类型等,

46、而且数组元素是变量。,8.2 枚举类型,8.2.2 枚举变量的声明定义了一个枚举类型,我们可以用它来定义变量。例如,在前面定义了枚举类型enum color,我们可以使用它来定义变量:enum color stop,go;或者为:enum color red,yellow,green stop,go;后面的stop,go是该类型的两个变量,它们的取值只能是red,yellow,green之一。例如:stop=red;go=green;,8.2 枚举类型,8.2.3 枚举类型变量的赋值和使用枚举类型在使用中有以下规定:1.枚举元素是常量在编译器中,枚举元素本身由系统定义了一个表示序号的数值,从0

47、开始顺序定义为0,1,2如在enum day中,Sun值为0,Mon值为1Sat值为6。例8.7 我们可以按整型数据输出枚举类型变量的值:程序清单 C08_7.cpp#include enum color red,yellow,green;,8.2 枚举类型,void main()enum color stop,go;/*声明枚举变量stop,go*/stop=red;/*为枚举变量赋值*/go=green;printf(枚举变量go的值是:%dn,go);printf(枚举变量stop的值是:%dn,stop);输出结果枚举变量go的值是:2枚举变量stop的值是:0程序中,语句“enum

48、color red,yellow,green;”在确定枚举值的同时分别为它们定义了表示序号的值:red为0,yellow为1,green为2。同时,枚举变量的值只能用赋值语句来获得。,8.2 枚举类型,2.允许在定义枚举类型时,指定枚举常量的值。例如:enum color red=3,yellow=1,green;这里,green的值从yellow的值顺序加1。即,green 的值是2。,8.2 枚举类型,3.枚举值可以作判断例如:if(stop=red)cout 请停车!n;4.整型与枚举类型是不同的数据类型,不能进行直接赋值例,错误的赋值:stop=2;/*stop是枚举类型*/不过,可以

49、通过强制类型转换,对枚举变量赋值整型值。例如:stop=(enum color)2;,8.2 枚举类型,8.2.4 枚举类型的应用举例例8.8 在屏幕上提示:请用户选择行走的方向,然后显示出所选方向。程序清单C08_8.cpp#include#include void main()char*question=请选择方向 1:西,2:北,3:东,4:南;char*pwest=你选择向西;char*pnorth=你选择向北;char*peast=你选择向东;char*psouth=你选择向南;enum location west=1,north=2,east=3,south=4;enum loca

50、tion direction;,8.2 枚举类型,int n;cout n;direction=(enum location)n;switch(direction)case west:cout pwest endl;break;case north:cout pnorth endl;break;case east:cout peast endl;break;case south:cout psouth endl;break;default:cout 在原地等待n;break;,8.2 枚举类型,输出结果请选择方向 1:西,2:北,3:东,4:南2你选择向北从上面这段程序可以看出,用枚举类型能够

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号