C大学基础教程第七章.ppt
C+大学基础教程,第7章 其它自定义数据类型 北京邮电大学电信工程学院 计算机技术中心,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-2-,第7章 其它自定义数据类型,C+语言不仅有丰富的基本数据类型,而且允许用户自己定义数据类型。,7.1 枚举型数据类型7.2 结构型数据类型7.3 联合型数据类型,第7章 C+其他自定义数据类型,7.1 枚举类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-5-,7.1 枚举类型,枚举型数据类型(简称枚举类型)有些问题中所处理数据的取值可以一一列举出来例:一周七天:星期日、星期1、星期2、星期3、星期4、星期5、星期6用户可以自己定义一种数据类型,把这种数据类型的变量的可能值一一列举出来。然后就可以使用这种数据类型来定义变量了。这种新的数据类型称为枚举类型,声明形式为:enum 枚举类型名枚举元素列表;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-6-,例如:enum weekdaysun,mon,tue,wed,thu,fri,sat;新的数据类型 枚举元素或枚举常量,7.1 枚举类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-7-,enum weekdaysun,mon,tue,wed,thu,fri,sat;定义一个weekday类型的变量:weekday day;变量day的取值范围:类型定义时,表里列举出来的七种标识符,把这些标识符看作符号常量。例如:day=sat;,7.1 枚举类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-8-,在类型定义之后,对枚举元素按常量处理,不能对它们赋值。sat=6;枚举元素具有默认值,它们依次为:0,1,2,。enum weekdaysun,mon,tue,wed,thu,fri,sat;也可以在类型声明时另行指定枚举元素的值。enum weekdaysun=7,mon=1,tue,wed,thu,fri,sat,使用枚举类型时要注意:,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-9-,枚举值可以进行关系运算。整数值不能直接赋给枚举变量;如需要将整数值赋给枚举变量,应进行强制类型转换.例:int x=2;weekday day;day=x;?day=(weekday)x;?,使用枚举类型时要注意:,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-10-,枚举常量在机器内部仍然是用整型数来存取定义某个枚举类型的变量时,分配几个字节的内存空间呢?(前面我们看到,枚举元素的默认值都是整数,可以给枚举元素指定值,也用整数,所以说,在计算机内部处理时,是把枚举类型按整型(int)对待的。),7.1 枚举类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-11-,例7.1,读入1-7之间的一个数代表今天,输出明天是星期几。,#include using namespace std;enum weekday sun=7,mon=1,tue,wed,thu,fri,sat;void main()coutn;weekday today=(weekday)n;weekday tomorrow=(weekday)(today+1);if(today=sun)tomorrow=mon;,if(today=0)tomorrow=(weekday)-1;switch(tomorrow)case sun:coutTomorrow is Sunday.endl;break;case mon:coutTomorrow is Monday.endl;break;case tue:coutTomorrow is Tuesday.endl;break;case wed:coutTomorrow is Wednesday.endl;break;,case thu:coutTomorrow is Thursday.endl;break;case fri:coutTomorrow is Friday.endl;break;case sat:coutTomorrow is Saturday.endl;break;default:coutinput error!endl;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-15-,例:,口袋中有红、黄、蓝、白、黑五种颜色的球若干个。每次从口袋中取出3个不同颜色的球,问有多少种取法。分析:由于球只能是五种颜色之一,故可用枚举类型表示球的颜色。设取出的球为i、j、k,根据题意,i、j、k分别可以有五种取值,且ijk。可以用穷举法,逐个检验每一种可能的组合,从中找出符合要求的组合并输出。,#includevoid main()enum colorred,yellow,blue,white,black;enum color print;int n,loop,i,j,k;char c;n=0;for(i=red;i=black;i+)for(j=red;j=black;j+)if(i!=j)/前两个球不同 for(k=red;k=black;k+),if(k!=i),switch(print)case red:coutred;break;case yellow:coutyellow;break;case blue:coutblue;break;case white:coutwhite;break;case black:coutblack;break;default:break;/end of for loop coutendl;/end of if/end of if couttotal:nendl;,7.2 结构类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-20-,结构型数据类型(简称结构类型)把现实生活中意义密切相关的一组数据组合成一个整体,即由各种数据类型(可以是基本数据类型或已声明的自定义数据类型)的数据组成一个集合,称为结构类型。,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-21-,结构的声明形式如下:struct 结构类型名 数据类型标识符1 成员名1;数据类型标识符2 成员名2;数据类型标识符n 成员名n;;,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-22-,例如:struct studentlong num;/学号char name20;/姓名 int age;/年龄 float score;/成绩;,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-23-,定义结构类型的变量:结构类型名 结构变量名;例:定义student类型的变量:student stu1;,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-24-,结构类型的变量所占的存储空间是结构中所有成员所占空间的总和 例 sizeof(student)=sizeof(long)+20*sizeof(char)+sizeof(int)+sizeof(float)sizeof(s1)=sizeof(student),结构类型的定义,struct studentlong num;char name20;int age;float score;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-25-,结构成员的访问格式:结构变量名.成员名例:student s1;s1.num=1;couts1.numendl;couts1.nameendl;,结构类型的定义,如同使用一个变量,如同使用一个数组,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-26-,给结构变量赋初值,可以在变量定义时同时设置初始值:student s2=20041118,”Li Li”,18,90;给结构变量赋值,也可以单独给各个成员赋值。例如:s1.num=20041118;strcpy(s1.name,”Li Li”);,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-27-,例7.2 结构类型的声明,变量的定义和初始化。,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-28-,/例7.2 结构类型的声明,变量的定义和初始化#include#include using namespace std;struct student/声明新的数据类型 long num;/学号 char name20;/姓名 char sex;/性别 int age;/年龄stu=20041118,Li Li,F,18;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-29-,void main()coutsetw(8)stu.numsetw(10)stu.name setw(3)stu.sexsetw(3)stu.ageendl;运行结果:20041118 Li Li F 18,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-30-,结构体可以由不同数据类型的成员构成,这些成员可能是基本数据类型,也可能是自定义的数据类型,比如已声明的另一个结构类型。例7.3 访问带有结构体类型成员的结构体变量。,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-31-,/例7.3 结构体定义的嵌套#include using namespace std;struct dateint year;int month;int day;,struct Weather date today;double temp;/温度 double wind;/风力;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-32-,void main()Weather today_weather=2004,11,30,10.0,3.1;couttoday_weather.today.year年 today_weather.today.month月 today_weather.today.day日的天气是:;cout 温度:today_weather.temp;cout 度,风力:today_weather.wind级 endl;运行结果:2004年11月30日的天气是:温度:10度,风力:3.1级,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-33-,属于同一结构类型的各个变量之间可以相互赋值,这一点和数组不同,C+规定,不能直接进行数组名的赋值,因为数组名是一个常量,而结构类型的变量可以赋值。不同结构的变量不允许相互赋值,即使这两个变量可能具有同样的成员。,结构类型的定义,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-34-,例:struct student int num;char name20;s1,s2;s1=1,”zhang”;s2=2.”zhao”;student si;si=s1;,例:struct person int ID;char name20;p1,p2;p1=1,”zhang”;p2=2.”zhao”;person pi;pi=p1;,pi=s1;/error!si=p1;/error!,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-35-,结构指针定义变量时,我们可以定义指向int型的指针变量,类似的,可以有指向结构型数据的指针变量。例:student*ps;,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-36-,可以将结构变量的地址赋给结构指针,使结构指针的指向确定。使用取地址“,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-37-,用结构指针访问结构成员时,用箭头操作符代替原来的点操作符。例:struct student int num;char name20;s1=1,”zhang”;student*ps=,7.2.2 结构类型的使用,输出同样内容,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-38-,使用new操作在堆中给结构指针分配空间。例如:student*ps=new student;coutnum;其中,ps-num等价于(*ps).num。注意程序结束之前,释放动态内存分配。delete ps;,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-39-,使用new操作在堆中给结构指针分配空间。例如:student*ps=new student30;delete ps;一般动态内存分配多用于申请一个较大的空间。,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-40-,实际编程中,经常使用结构表示实际对象,例如:图书管理系统中的图书的表示学生管理系统中的学生的表示公司管理系统中职工的表示模式识别中特征的表示,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-41-,每个员工的信息包括姓名、工作证号、薪水,定义为结构类型。定义结构指针,通过结构指针访问结构成员,输出显示员工的信息,例7.4 结构指针的定义和使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-42-,#include#include using namespace std;struct Employee char name20;unsigned long id;float salary;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-43-,void main()Employee pr1;Employee*prPtr;prPtr=,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-44-,声明一个结构类型后,就可以用来组成更复杂的数据类型。可以象定义基本数据类型的数组一样定义结构类型的数组,称为结构数组。结构数组的每个元素都是该结构类型的变量。,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-45-,#include using namespace std;struct Employee char name20;unsigned long id;float salary;Employee allone6=zhang,12345,3390.0,wang,13916,4490.0,zhou,27519,3110.0,meng,42876,6230.0,yang,23987,4000.0,chen,12335,5110.0;,例7.5 公司有六个员工,把他们按工资由低到高排序。,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-46-,void main()Employee temp;for(int i=1;i allonej+1.salary)/比较工资成员 temp=allonej;/结构变量的交换 allonej=allonej+1;allonej+1=temp;for(int k=0;k6;k+)/输出 cout allonek.name allonek.id allonek.salaryendl;,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-47-,结构型变量作函数的形式参数,参数传递方式为值传递,这时实参结构变量中所有成员的值都将被一一复制到形参变量空间中的相应成员。结构型引用变量作函数的形式参数,参数传递方式为地址传递方式,这时仅仅把实参结构变量的地址传递给形参,形参是实参的别名,共用同一地址空间。,7.2.2 结构类型的使用,/例7.6 用结构变量作为函数参数#include using namespace std;struct Employee char name20;unsigned long id;float salary;void Print(Employee e)cout e.name e.id e.salary endl;,void main()Employee allone4=zhang,12345,3390.0,wang,13916,4490.0,zhou,27519,3110.0,chen,12335,5110.0;for(int i=0;i4;i+)Print(allonei);运行结果:zhang 12345 3390wang 13916 4490zhou 27519 3110chen 12335 5110,/例7.7 用结构变量的引用传递函数参数#include using namespace std;struct Employee char name20;unsigned long id;float salary;void Print(Employee,Employee allone4=zhang,12345,3390.0,wang,13916,4490.0,zhou,27519,3110.0,chen,12335,5110.0;void main()for(int i=0;i4;i+)Print(allonei);,这两个例子中,引用作形式参数,函数调用所需传递的数据较少。,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-52-,一个函数的参数可以是某个结构类型,同样道理,函数的返回值也可以是某个结构类型。以结构变量作为函数的返回值,到主函数中需要把结构值复制给主函数中的结构变量,当结构成员很多时,同样存在执行效率低的问题。因此,也可以用结构的引用(或指针)作为返回值。但是要注意:不能返回一个局部结构变量的引用或指针。,7.2.2 结构类型的使用,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-53-,/例7.8 用结构变量的引用作为函数的返回值#include using namespace std;struct Employee char name20;unsigned long id;float salary;temp;/定义全局结构变量,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-54-,Employee,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-55-,void main()Employee e3;for(int i=0;i3;i+)ei=Get();Print(ei);,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-56-,运行结果:Please enter a name for one employee:zhaoPlease enter ones id number and his salary:2355 3000.0zhao 2355 3000Please enter a name for one employee:qianPlease enter ones id number and his salary:655 5000.0qian 655 5000,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-57-,Please enter a name for one employee:wangPlease enter ones id number and his salary:1998 4500.0wang 1998 4500,7.3 联合类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-59-,有时需要使几个不同类型的变量共用同一组内存单元,这时可以声明一个联合型数据类型,语法形式为:union 联合类型名数据类型标识符1 成员名1;数据类型标识符2 成员名2;数据类型标识符n 成员名n;;,7.3 联合类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-60-,例如:union uareachar c-data;short s-data;long l-data;ux;,新定义的联合类型三个成员,它们共用内存空间uarea类型的变量ux,7.3 联合类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-61-,图7-2 联合型变量的内存图,同一段内存用来存放几种不同类型的成员,但在某一时刻只能存放其中一种,而不是同时存放几种。联合变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。联合变量的地址和它的各个成员的地址都是同一地址。,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-62-,例7-9 设有若干个人员的信息,其中有学生和教师。从键盘输入相关人员的信息。,/例7.9 联合体的应用#include using namespace std;#define NUM 100struct person int num;char name10;char sex;char job;/人员的类别union/无名联合作为结构体的内嵌成员int classes;/为学生存放班级char position10;/为教师存放职称;pNUM;,联合类型可以不声明名称,称为无名联合,常用作结构类型的内嵌成员.,void main()for(int i=0;ipi.numpi.namepi.sexpi.job;if(pi.job=s)cinpi.classes;else if(pi.job=t)cinpi.position;else coutinput error!endl;for(i=0;i NUM;i+)/按学生或教师显示信息 if(pi.job=s)coutpi.nameis a student of class“pi.classes.endl;else if(pi.job=t)coutpi.nameis a teacher,he is a“pi.position.n;,运行结果:9910401 zhang m s 104/输入信息2355 wang f t profzhang is a student of class 104./输出信息wang is a teacher,he is a prof.,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-66-,使用联合型变量时注意:同一段内存用来存放几种不同类型的成员,但在某一时刻只能存放其中一种,而不是同时存放几种。联合变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。联合变量的地址和它的各个成员的地址都是同一地址。不能对联合变量名赋值,也不能在定义时初始化。不能用联合变量作为函数参数或返回值。,7.3 联合类型,2023/11/7,北京邮电大学电信工程学院计算机技术中心,-67-,总结,用户自定义的数据类型和系统预定义的数据类型,它们的地位是等价的。声明一个新的数据类型时并不分配内存,只有在定义新数据类型的变量时才发生内存分配。枚举类型实际上是有限个整数的集合。结构变量所占的内存长度是各个成员占的内存长度之和,每个成员都有自己的内存单元;联合变量所占的内存长度等于最长的成员的长度,无论联合类型有多少成员,它们共用内存单元。,