资源描述
Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,Logo,*,Click to edit Master title style,第,7,章自定义数据类型,C+,程序设计,本章主要内容,1,2,3,7.1,结构体类型,7.3,枚举类型,7.2,共用体,类型,Logo,数据类型回顾:,基本的数据类型:,int,、,float,、,double,、,char,、,bool,、,指针类型、引用类型,用户自定义数据类型:,数组,结构体,(,structure),类型,共用体,(,union),类型,枚举,(,enumeration),类型,类,(,class),类型,Logo,7.1,结构体类型,7.1.1,结构体概述,有时需要将,不同类型的数据组合成一个有机的整体,,以供用户方便地使用。这些组合在一个整体中的数据是互相联系的。例如,一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项,都是这个学生的属性。,图,7.1,Logo,7.1.1,结构体概述,利用,结构体,将若干个类型不同的数据项组合在一起。它相当于,SQL Server,中的,记录,(record),。,例如,定义一个学生的结构体:,struct,Student,/,声明一个结构体类型,Student,int num;,/,包括一个整型变量,num,char name20;,/,包括一个字符数组,name,char sex;,/,包括一个字符变量,sex,int age;,/,包括一个整型变量,age,float score;,/,包括一个单精度型变量,char addr30;,/,包括一个字符数组,addr,;,/,最后有一个分号,Logo,7.1.1,结构体概述,struct,是声明结构体类型时所必须使用的关键字。,Student,是一个结构体类型名,与,int,、,char,、,float,、,double,等一样,可用来定义变量,只不过结构体类型需要事先由用户自己声明。,声明一个结构体类型的一般形式为,:,struct,结构体类型名,成员表列;,;,Logo,7.1.1,结构体概述,声明结构体类型的位置:,(1),一般在文件的开头,,在所有函数,(,包括,main,函数,),之前,,以便本文件中所有的函数都能利用它来定义变量。,(2),也可以在函数中声明结构体类型。,Logo,7.1.2,结构体类型变量,前面只是指定了一种结构体类型,它相当于一个模型,但其中并无具体数据,系统也不为之分配实际的内存单元。,为了能在程序中使用结构体类型的数据,应当定义,结构体类型的变量,,并在其中存放具体的数据。,1.,定义结构体类型变量的方法,可以采取以下,3,种方法定义结构体类型的变量。,(1),先声明结构体类型再定义变量名,Logo,7.1.2,结构体类型变量,struct,Student,/,声明一个结构体类型,Student,int num;,/,包括一个整型变量,num,char name20;,/,包括一个字符数组,name,char sex;,/,包括一个字符变量,sex,int age;,/,包括一个整型变量,age,float score;,/,包括一个单精度型变量,char addr30;,/,包括一个字符数组,addr,;,Student,student1,student2,;,Logo,7.1.2,结构体类型变量,(2),在声明类型的同时定义变量,struct,Student,int num;,char name20;,char sex;,int age;,float score;,char addr30;,student1,student2,定义的一般形式为,:,struct,结构体名,成员表列,变量名表列;,Logo,7.1.2,结构体类型变量,(3),直接定义结构体类型变量,struct,int num;,char name20;,char sex;,int age;,float score;,char addr30;,student1,student2,;,提倡使用先定义类型后定义变量的第,(1),种方法。,struct,/,结构体类型名省略,成员表列,变量名表列;,Logo,7.1.2,结构体类型变量,说明:,(1),类型与变量是不同的概念,不要混淆。,只能对结构体变量中的成员赋值,,,而不能对结构体类型赋值。,在编译时,是不会为类型分配空间的,只为变量分配空间。,(2),对结构体中的成员,可以单独使用,它的作用与地位相当于普通变量。,(3),成员也可以是一个结构体变量。,Logo,struct,Date,/,声明一个结构体类型,Date,int,month;,int,day;,int,year;,;,struct,Student,/,声明一个结构体类型,Student,int,num;,char name20;,char sex;,int,age;,Date,birthday;,char,addr,30;,student1,student2;,Logo,7.1.2,结构体类型变量,Student,的结构见图,7.3,所示。,Logo,7.1.2,结构体类型变量,2.,结构体变量的初始化,Student,student1,=10001,,,Zhang Xin,M,19,90.5,Shanghai;,3.,结构体变量的引用,(1),将一个结构体变量的值赋给另一个具有相同结构的结构体变量。如,:,student1,=,student2;,(2),引用结构体变量中的一个成员的方式:,结构体变量名,.,成员名,如:,student1.num=1001;,Logo,7.1.2,结构体类型变量,(3),如果成员本身也是一个结构体类型,,则要用若干个成员运算符,一级一级地找到最低一级的成员。,如果想引用,student1,变量中的,birthday,成员中的,month,成员,则,必须逐级引用,:,student1,.birthday.,month,Logo,7.1.2,结构体类型变量,(4),不能将一个结构体变量作为一个整体进行输入和输出。如:,cout,student1;,只能对结构体变量中的各个成员分别进行输入和输出。,(5),对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算种类)。,student2.score,student1.score,;,sum,student1.score,student2.score,;,student1.age+,;,/“.”,运算符的优先级最高,+student1.age,;,Logo,7.1.2,结构体类型变量,(6),可以引用结构体变量成员的地址,也可以引用结构体变量的地址。如,cout,/,输出,student1,的首地址,cout,/,输出,student1.age,的地址,结构体变量的地址主要用作函数参数,将结构体变量的地址传递给形参。,Logo,7.1.4,结构体数组,一个结构体变量中可以存放一组数据(如一个学生的学号、姓名、成绩等数据)。如果有,10,个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。,结构体数组与以前介绍过的数值型数组的不同之处在于:每个数组元素都是一个结构体类型的数据,它们都分别包括各个成员项。,Logo,7.1.4,结构体数组,1.,定义结构体数组,和定义结构体变量的方法相仿,定义结构体数组时只需声明其为数组即可。如,struct,Student,/,声明结构体类型,Student,int,num;,char name20;,char sex;,int,age;,float score;,char,addr,30;,;,Student,stu,3;/,定义,Student,类型的数组,stu,Logo,7.1.4,结构体数组,也可以直接定义一个结构体数组,如,struct,Student,int,num;,char name20;,char sex;,int,age;,float score;,char,addr,30;,stu,3;,struct,int,num;,char name20;,char sex;,int,age;,float score;,char,addr,30;,stu,3;,或,Logo,7.1.4,结构体数组,见图,7.4,。数组各元素在内存中连续存放,见图,7.5,示意。,Logo,7.1.4,结构体数组,2.,结构体数组的初始化,对结构体数组可以初始化。如,struct,Student,int,num;,char name20;,char sex;,int,age;,float score;,char,addr,30;,sty3,=,10101,LiLin,M,18,87.5,Beijing Road,10102,Zhang Fun,M,,,19,99,Shanghai Road,10104,Wang Min,F,20,78.5,Zhongshan,Road,;,Logo,7.1.4,结构体数组,3.结构体数组应用举例,下面举一个简单的例子来说明结构体数组的定义和引用。,例7.2 对候选人得票的统计程序。设有3个候选人,最终只能有1人当选为领导。今有10个人参加投票,从键盘先后输入这10个人所投的候选人的名字,要求最后输出这3个候选人的得票结果。,可以定义一个候选人结构体数组,包括3个元素,在每个元素中存放有关的数据。,程序如下:,Logo,struct,Person,/,声明结构体类型,Person,char name20;,int count;,;,int,main(),Person,leader3=Li,0,Zhang,0,Fun,0;,/,定义,Person,类型的数组,内容为3个候选人的姓名和当前的得票数,int,i,j;,char leader_name20;,/,leader_name,为投票人所选的人的姓名,for(i=0;ileader_name;/,先后输入10张票上所写的姓名,for(j=0;j3;j+),/,将票上姓名与3个候选人的姓名比较,Logo,if(strcmp(leader_name,leaderj,.,name,)=0),leaderj.,count,+;,/,如果与某一候选人的姓名相同,就给他加一票,coutendl;,for(i=0;i3;i+)/,输出3个候选人的姓名与最后得票数,cout,leaderi.,name,:,leaderi.,count,endl;,return 0;,Logo,7.2 共用体,7.2.1 共用体的概念,有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可把一个整型变量、一个字符型变量、一个双精度型变量放在同一个地址开始的内存单元中(见图7.12)。,Logo,7.2 共用体,7.2.1 共用体的概念,这种使几个不同的变量共占同一段内存的结构,称为共用体(,union),类型的结构(联合体)。,声明共用体类型的一般形式为,union,共用体类型名,成员表列,;,定义共用体变量的一般形式为,共用体类型名,共用体变量名,;,Logo,7.2 共用体,union,data,int,i;,char,ch,;,double d;,a,b,c;,(,有共用体类型名),union,int,i;,char,ch,;,double d;,a,b,c;,(,无共用体类型名),当然也可在声明共用体类型的同时定义共用体变量,,也可没有共用体类型名而直接定义共用体变量。,可以看到,“共用体”与“结构体”的定义形式相似。但它们的含义是不同的。,结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。,共用体变量所占的内存长度等于最长的成员的长度。,Logo,7.2.2 对共用体变量的访问方式,不能引用共用体变量,而只能引用共用体变量中的成员。,例如,下面的引用方式是正确的:,a.i(,引用共用体变量中的整型成员,i),a.ch(,引用共用体变量中的字符型成员,ch),a.f(,引用共用体变量中的双精度型成员,d),不能只引用共用体变量,例如,couta;,是错误的,应该写成,cout,a.i,;,或,cout,a.ch,;,等。,Logo,7.2.3 共用体类型数据的特点,(1)使用共用体变量的目的是希望用同一个内存段存放几种不同类型的数据。,但请注意:,在每一瞬时只能存放其中一种,而不是同时存放几种。,(2)能够访问的是共用体变量中最后一次被赋值的成员,,在对一个新的成员赋值后原有的成员就失去作用,。,(3)共用体变量的地址和它的各成员的地址都是同一地址。,(4)不能对共用体变量名赋值;不能企图引用变量名来得到一个值;,不能在定义共用体变量时对它初始化;,不能用共用体变量名作为函数参数。,Logo,例7.7 设有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、年级。教师的数据包括:姓名、号码、性别、职业、职务。可以看出,学生和教师所包含的数据是不同的。现要求把它们放在同一表格中,见图7.13。,对第5项可以用共用体来处理(将,class,和,position,放在同一段内存中)。,Logo,#,include,#include,#include,/,因为在输出流中使用了控制符,setw,using namespace std;,struct,int num;,char name10;,char sex;,char job;,union,P,/,声明共用体类型,int bj;/,班级,char position10;/,职务,category;/,成员,category,为共用体变量,person2;/,定义共用体数组,person,,含两个元素,Logo,int main(),int i;,for(i=0;i,personi.num,personi.name,personi.sex,personi.job,;,if(personi.job=s),cin,personi.category.bj,;/,若是学生则输入班级,else if(personi.job=t),cin,personi.category.position,;/,若是教师则输入职务,coutendlNo.Name sex job bj/positionendl;,Logo,for(i=0;i2;i+),if(personi.job=s),coutpersoni.numsetw(6)personi.name personi.sex personi.jobsetw(10)personi.category.bjendl;,else,coutpersoni.numsetw(6)personi.name personi.sex personi.jobsetw(10)personi.category.positionendl;,return 0;,Logo,7.3 枚举类型,如果一个变量只有几种可能的值,可以定义为枚举(,enumeration),类型。,所谓“枚举”是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。,Logo,7.3 枚举类型,声明枚举类型用,enum,开头。,enum,枚举类型名,枚举,常量,表列,;,例如,enum weekdaysun,mon,tue,wed,thu,fri,sat;,在声明了枚举类型之后,可以用它来定义变量。如,weekday workday,week_end;,Logo,例7.8 口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中任意取出3个球,问得到3种不同颜色的球的可能取法,输出每种排列的情况。,#,include,#include /,在输出时要用到,setw,控制符,using namespace std;,int main(),enum color red,yellow,blue,white,black;,color,pri;/,定义,color,类型的变量,pri,int i,j,k,n=0,loop;,for(i=red;i=black;i+)/,当,i,为某一颜色时,for(j=red;j=black;j+)/,当,j,为某一颜色时,if(i!=j)/,若前两个球的颜色不同,for(k=red;k=black;k+),/,只有前两个球的颜色不同,才需要检查第3个球的颜色,Logo,if(k!=i)&(k!=j)/3,个球的颜色都不同,n=n+1;/,使累计值,n,加1,coutsetw(3)n;/,输出当前的,n,值,字段宽度为3,for(loop=1;loop=3;loop+)/,先后对3个球作处理,switch(loop)/loop,的值先后为1,2,3,case 1:pri=color(i);break;,/color(i),是强制类型转换,使,pri,的值为,i,case 2:pri=color(j);break;/,使,pri,的值为,j,case 3:pri=color(k);break;/,使,pri,的值为,k,default:break;,Logo,switch(pri)/,判断,pri,的值,输出相应的“颜色”,case red:coutsetw(8)red;break;,case yellow:coutsetw(8)yellow;break;,case blue:coutsetw(8)blue;break;,case white:coutsetw(8)white;break;,case black:coutsetw(8)black;break;,default :break;,coutendl;,couttotal:nendl;/,输出符合条件的组合的个数,return 0;,Logo,Thank you,
展开阅读全文