资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,本章介绍的数据类型是由各种基本数据类型的数据,组合而成的导出数据类型,:,结构体,共用体,枚举类型,但结构体、共用体和枚举类型各有不同的特点。,第,7,章 结构体、共同体和枚举类型,第,7,章 结构体、共同体和枚举类型,7.1,结构体的定义与应用,7.3,共同体的定义与应用,7.4,枚举类型,unsigned,long,7.1,结构体,7.1.1,结构体类型的说明,学号,姓名,性别,年龄,成绩,籍贯,lixin,18,M,Nanjing,87.5,char,name5,char,int,float,char,addr7,要将这份档案组合成,一个,数据项,那么,无论用前面介绍的哪种类型的数据,包括数组都不可能。因为档案中不是同一种数据类型。,2095105,但是,处理文档是计算机办公的特长。为此,,c+,设计了另一种导出类型的数据。它把各种类型的数据结合在一起,成为一种数据类型,这种类型称为,结构体,类型,。,如果有这样一份档案,数据,类型,struct,student,unsigned long,num;,char,name5;,char,sex;,int,age;,float,score;,char,addr7;,s;,定义结构体的,指令标识符,结构体的类型标识符,与,int,float,等性质相同,含,6,个成员的,结构体家族,全局量,s,被定义为,结构体类型的变量,unsigned,long,学号,姓名,性别,年龄,成绩,籍贯,lixin,18,M,Nanjing,87.5,char,name5,char,int,float,char,addr7,2095105,数据,类型,定义如下:,7.1.1,结构体类型的说明,s,系统怎样为变量,s,分配单元呢?请看,struct,student,unsigned long,num;,char,name5;,char,sex;,int,age;,float,score;,char,addr7;,s;,num,name,sex,age,score,addr,定义,了结构体类型,后,,,其变量也可这样定义,void,main(),student,s;,.,编译结果一样,;,加分号,7.1.1,结构体类型的说明,void,main(),struct,student,unsigned long,num;,char,name5;,char,sex;,int,age;,float,score;,char,addr7;,s;,.,s,也可以这样定义,num,name,sex,age,score,addr,因为没有类型名,无法再定义其它变量,7.1.1,结构体类型的说明,结构体,是各种不同类型数据的组合,编程者可按实际需要进行这种组合。如:图书馆的书有若干特点:,char bname100;,char author80;,float price;,int,id;,struct,book,;,book,类型的成员变量,注意,:book,是一种,数据类型,,而,不是变量,。,书名,(,字符串,),作者,(,字符串,),定价,(,实数类型,),编号,(,整型,),7.1.1,结构体类型的说明,7.1.2,结构体与数组间的区别,数组,所有的元素都具有,相同的,数据类型。,int,array10;,定义的是数组,变量,。,数组元素用下标,来访问。如:,array1,结构体,它用,各种不同,数据类型的,成员变量,来组成和描述一个对象或者一个概念。,上例中定义的是表示“教材课本”的结构,类型,。,book,Cpp,;,该语句用,book,类型定义变量,,Cpp,是,book,类型的,变量,。,成员变量用,“,.”,来访问如:,Cpp.author,表示,Cpp,变量的,作者,成员,void,main(),student,s;,cin,s,.name,;,cin,s,.addr,;,s,.score,=87.5;,s,.age,=19;,s,.sex,=M;,s,.num,=2095105;,.,s,num,name,sex,age,score,addr,struct,student,unsigned long,num;,char,name6;,char,sex;,int,age;,float,score;,char,addr8;,;,执行语句时,假如键入如下数据:,lixin,Nanjing,传递数据时,系统是这样寻址的:,l,i,x,i,n,7.1.3,结构体成员的使用,void,main(),student,s;,cin,s,.name,;,cin,s,.addr,;,s,.score,=87.5;,s,.age,=19;,s,.sex,=M;,s,.num,=2095105;,.,s,num,name,sex,age,score,addr,struct,student,unsigned long,num;,char,name6;,char,sex;,int,age;,float,score;,char,addr8;,;,执行语句时,假如键入如下数据:,lixin,Nanjing,传递数据时,系统是这样寻址的:,l,i,x,i,n,N,a,n,j,i,n,g,void,main(),student,s;,cin,s,.name,;,cin,s,.addr,;,s,.score,=87.5;,s,.age,=19;,s,.sex,=M;,s,.num,=2095105;,.,s,num,name,sex,age,score,addr,struct,student,unsigned long,num;,char,name6;,char,sex;,int,age;,float,score;,char,addr8;,;,显然,以下过程完全相同。访问时,l,i,x,i,n,N,a,n,j,i,n,g,87.5,s,.addr,变量名,成员名,分隔符,main(),struct,student,unsigned long,num;,char,name6;,char,sex;,int,age;,float,score;,char,addr8;,s=2095105,“lixin”,M,19,87.5,“Nanjing”;,.,初始化定义,数据次序不能乱,不可有空缺,s,num,name,sex,age,score,addr,l,i,x,i,n,N,a,n,j,i,n,g,87.5,2095105,M,19,编译时,main(),student,s43,;,.,struct,student,unsigned long,num;,char,name6;,char,sex;,int,age;,float,score;,char,addr8;,;,结构体类型的数组,编译系统给它分配,43,个结构体类型的元素,7.1.4,结构体数组,S,0,num,name,sex,age,score,addr,S,1,num,name,sex,age,score,addr,S,42,num,name,sex,age,score,addr,.,7.1.4,结构体数组,结构体类型变量进行输入,/,输出时,不可以作整体输入。即:,cin,book1;,而必须对成员变量分别输入,/,输出:,cin,book1.bname;,cin,book1.author;,等,结构体变量各成员变量在内存中是,连续存放,的。,struct,book char bname100;char author80;float price;,int,id;book1;,共,100,字节,共,80,字节,共,4,字节,bname,author,price,共,4,字节,id,变量,book1,可以用结构体类型定义数组,如:,book books10;,结构体类型的成员变量可以含有数组变量。,问题:输入语句,cin,books.price;,有没有问题?为什么?,结构体与数组,答:因为这里,books,是数组名,不是变量名。,结构体可以作为函数的参数,也可作为函数的返回值,函数的参数为结构体类型,形参与实参的结合属于值调用方式。,要提高其运行效率,,可采用,引用类型,的结构体类型变量。(参见,P124,例,7.4),结构体与函数,7.1.5*,结构体,关于静态成员的使用,#include,iostream.h,struct,date,int,year,month,day;,;,struct,s,char name10;,int,id;,static,date d;,s1,s2;,date s:d,=2000,1,1;,void main(),在结构体的所有变量中,编译系统仅为静态成员分配一个存储空间。,即:所有该结构类型变量的静态成员共享同一存储空间。,更改,s1,的,d,成员值,其他,s,类型变量,(,如,s2),的,d,成员值也会改变,(,虽然我们没有用额外的语句来改变他的值,),。,结构类型中的静态成员使用前必须进行,定义性,说明,可在文件作用域的某一个地方,且仅允许一次,.,格式中使用,作用域运算符,:,date,s:d,;,含有静态成员的结构类型必须说明为,全局,的,7.1.6,一些要注意的问题,定义结构体的成员类型时除了,static,存储类型外,不允许有其它存储类型。而用,static,存储类型定义的成员变量仅作特殊用途时使用,struct,stru,static,int,id;,auto,int,eng;,结构体变量,的存储类型说明方法与以前讲的一样:,static,stru,s1,;extern,stru,s2,;auto,stru,s3,;,问题,:请解释上面各条变量定义语句中各标识符的含义,如,static,stru,s1,等。,7.3,共同体,union,计算机的容量随着科技的发展已越来越大,,人们对存储器是否够用已较少关注。但是,十几年前却并不乐观。为此,人们想了许多办法来提高资源的利用率,采用共同体类型的数据就是一例。,我们知道,一个程序中有若干个语句,计算机在执行某个语句时,就要访问这个语句中的变量。而其它语句以及其中的其它变量却处于临时静止状态。尽管是临时静止,如果不是寄存器变量,它占用的资源却要等到所在函数执行结束才释放。,有没有办法这样做,当变量处于静止状态,哪怕是临时静止,也让它把资源让出来呢?比如说,把我们这个班级当作变量,这间教室当作存储器,下一个小时我们不上课,就让出来。但这间教室却不让它闲着,而是另一个班级上课。答案当然是肯定的,这种办法就是,C+,中提供的共同体类型的数据。,我们的教材中又将共同体称为联合体。它的定义形式与结构体很相似,只不过把,struct,改成,union,。例如:,union,data,char,a;,int,b3;,float,s;,s;,union,data,char,a;,int,b3;,float,s;,;,union,char,a;,int,b3;,float,s;,s;,定义联合体的,指令标识符,联合体的,类型标识符,联合体的成员,联合体变量,不定义联合体,类型,直接定义,s,为,联合体变量,7.3,共同体,union,所谓共同体,本例中就是指下面三个成员共同享用,一个,存储区。存储区的大小则由三者中用量最大者决定。在某一个时刻,当变量,a,使用存储区时,数组,s,和变量,b,就不能使用,要让出来。这样就使该存储区的空间获得充分利用,达到节省资源的目的。,union,data,char,a;,int,b3;,float,s;,s;,共同体的定义和用法与结构体基本相同,详细描述参阅,P128130,。,7.3,共同体,union,7.3.2,共用体与结构体区别,union,utype,int,i;,char,ch,;,;,struct,stype,int,i;,char,ch,;,;,data.i,data.ch,data.i,data.ch,地址增加,人们在阅读程序,尤其是语句较多或者逻辑关系比较复杂的程序时,就不象阅读文学作品那样轻松。其中一个很重要的原因就是程序中的标识符不象文学作品那样可以顾名思义。,为了提高人们阅读兴趣和效率,,C+,也与其它高级语言一样,构造了一种,可以顾名思义,的数据类型,称为,枚举类型,。例如,第,7.4,枚举类型,enum,enum,weekdaysun,,,mon,,,tue,,,wed,,,thu,,,fri,,,sat;,上面声明了一个枚举类型,weekday,,,花括号中,sun,mon,sat,等称为枚举元素或枚举常量。,表示这个类型的变量的值只能是以上,7,个值之一,它们是用户自己定义的标识符。,声明枚举类型的一般形式为,enum,枚举类型名,枚举常量表列,;,在声明了枚举类型之后,可以用它来定义变量。如,weekday,workday,week_end,;,这样,,workday,和,week_end,被定义为枚举类型,weekday,的变量。,7.4,枚举类型,根据以上对枚举类型,weekday,的声明,枚举变量的值只能是,sun,到,sat,之一。例如,workday=,mon,;,week_end,=sun;,也可以直接定义枚举变量,如,enumsun,,,mon,,,tue,,,wed,,,thu,,,fri,,,sat,workday,week_end,说明,:,(1),对枚举元素,按常量处理,,故称,枚举常量,。,(2),枚举元素作为常量,它们是有值的,,C+,编译按定义时的顺序对它们赋值为,0,1,2,3,。也可以在声明枚举类型时另行指定枚举元素的值。,枚举类型变量的使用,枚举变量可以与同类型的枚举变量做判断比较(关系运算)。,可将枚举常量赋值给枚举类型变量,也可在同类型枚举变量间相互赋值。,但一个整数不能直接赋给一个枚举变量。,workday=6 workday=sun,枚举类型变量不能直接从键盘输入,cin,workday;,但可以直接输出。,例,7.7,口袋中有红、黄、蓝、白、黑,5,种颜色的球若干个。每次从口袋中任意取出,3,个球,问得到,3,种不同颜色的球的可能取法,输出每种排列的情况。,#include,#include /,在输出时要用到,setw,控制符,using namespace std;,int,main(),enum,color red,yellow,blue,white,black;/,声明枚举类型,color,color,pri,;/,定义,color,类型的变量,pri,int,i,j,k,n=0,loop;/n,是累计不同颜色的组合数,for(i=red;i=black;i+)/,当,i,为某一颜色时,for(j=red;j=black;j+)/,当,j,为某一颜色时,if(i!=j)/,若前两个球的颜色不同,for(k=red;k=black;k+)/,只有前两个球的颜色不同,才需要检查第,3,个球的颜色,if(k!=i)&(k!=j)/3,个球的颜色都不同,n=n+1;/,使累计值,n,加,1,cout,setw(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;,switch(,pri,)/,判断,pri,的值,输出相应的“颜色”,case red:,cout,setw(8)red;break;,case yellow:,cout,setw(8)yellow;break;,case blue:,cout,setw(8)blue;break;,case white:,cout,setw(8)white;break;,case black:,cout,setw(8)black;break;,default :break;,cout,endl,;,cout,total:n,endl,;/,输出符合条件的组合的个数,return 0;,运行结果如下,:,1 red yellow blue,2 redyellow white,3 red yellow black,58 blackwhitered,59black whiteyellow,60 black whiteblue,total:60,不用枚举常量,而用常数,0,代表“红”,,1,代表“黄”,也可以。但显然用枚举变量更直观,因为枚举元素都选用了令人“见名知意”的标识符,而且枚举变量的值限制在定义时规定的几个枚举元素范围内,如果赋予它一个其他的值,就会出现出错信息,便于检查。,#include,enum,grade,math,phy,eng,com,d,;,void main(),grade,scor,;,int,i;,int,score6,d,;,for(i,=1;i=5;i+),for(,scor,=,math,;,scor,scoreiscor,;,for(i,=1;i=5;i+),for(scor,=,math;scor,=,com;scor,=(grade)(int)scor+1),cout,scorei,scor,=,scoreiscor,t;,cout,endl,;,7.4,枚举类型,应用,例:叙述程序的功能,注意枚举类型成员:,d,的使用。,定义枚举类型,定义枚举变量,枚举常数定义数组下标,习题:,P135,4,5,6,7,第,7,章 结构体、共同体和枚举类型,第,7,章 结构体、共同体和枚举类型学习要求,了解,struct,结构体类型的特点;,了解共同体特点;,了解枚举类型的语法和语义;,理解自定义数据类型的用途和定义方法,掌握自定义类型的使用方法。,
展开阅读全文