版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第八章结构体、共用体和枚举类型8.1
结构体8.2
共用体8.3
枚举类型8.4
用typedef定义类型/1结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-------自定义数据类型struct[结构体名]{
类型标识符成员名;类型标识符成员名;
…………….};成员类型可以是基本型或构造型struct是关键字,不能省略合法标识符可省:无名结构体8.1.1结构体类型声明8.1结构体结构体类型定义/2例struct
student{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};namenumsexagescoreaddr2字节2字节20字节1字节4字节30字节……..结构体类型定义描述结构的组织形式,不分配内存结构体类型定义的作用域8.1结构体structstudent应作为一个类型整体,num,name[20]等都只是其中的成员,且struct及“}”后的“;”不能省略。/38.1结构体例个人数据:包含姓名、性别、年龄、身高、体重、住址:structperson{charname[20];/*姓名*/charsex;/*性别*/intage;/*年龄*/floatheight;/*身高*/floatweight;/*体重*/charaddr[50];/*住址*/};structdate{intyear;/*年*/month;/*月*/day;/*日*/};例日期,包括年、月、日:/48.1结构体如职工信息结构体类型为:structperson{charname[20];/*姓名*/charaddress[40];/*地址*/floatsalary;/*工资*/floatcost;/*扣款*/structdatehiredate;
/*聘任日期*/};结构体类型可以嵌套定义
即一个结构体类型中的某些成员又是其他结构体类型
/58.1结构体8.1.2结构体变量的定义先定义结构体类型,再定义结构体变量一般形式:struct结构体名{
类型标识符成员名;类型标识符成员名;
…………….};struct结构体名变量名表列;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};structstudentstu1,stu2/6定义结构体类型的同时定义结构体变量一般形式:
8.1结构体struct结构体名{
类型标识符成员名;类型标识符成员名;
…………….}变量名表列;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;/78.1结构体直接定义结构体变量一般形式:
struct{
类型标识符成员名;类型标识符成员名;
…………….}变量名表列;例struct{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;用无名结构体直接定义变量只能一次/88.1结构体说明:结构体类型与结构体变量概念不同类型:不分配内存;变量:分配内存类型:不能赋值、存取、运算;变量:可以结构体可嵌套结构体成员名与程序中变量名可相同,不会混淆结构体类型及变量的作用域与生存期/98.1结构体8.1.3结构体变量的引用引用规则结构体变量不能整体引用,只能引用变量成员引用方式:结构体变量名.成员名成员(分量)运算符优先级:1结合性:从左向右如果结构体变量类型相同,可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用例;stu1=stu2;例:stu1.birthday.day=23;stu1.birthday.month=8;stu1.birthday.year=2003;/108.1结构体8.1.4结构体变量的使用1、结构体变量的初始化形式一:struct结构体名{
类型标识符成员名;类型标识符成员名;
…………….};struct结构体名结构体变量={初始数据};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudentstu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};/118.1结构体形式二:struct结构体名{
类型标识符成员名;类型标识符成员名;
…………….}结构体变量={初始数据};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};/128.1结构体形式三:struct{
类型标识符成员名;类型标识符成员名;
…………….}结构体变量={初始数据};例struct{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};/138.1结构体2、结构体变量的输入输出不允许对结构体变量进行整体的输入输出如:scanf(“%s%c%d%f”,&stu1);structstudent{intnum;intage;floatscore;}stu;voidmain(){printf("Enternum,age,score:");scanf("%d,%d,%f",&stu.num,&stu.age,&stu.score);printf("num:%d,age:%d,score:%.1f\n",stu.num,stu.age,stu.score);}程序运行过程:Enternum,age,score:1001,19,98.5↙num:1001,age:19,score:98.5/14结构体数组的定义形式一:
structstudent{intnum;charname[20];charsex;intage;};structstudentstu[2];形式二:structstudent{intnum;charname[20];charsex;intage;}stu[2];形式三:struct{intnum;charname[20];charsex;intage;}stu[2];numnamesexagenumnamesexagestu[0]stu[1]25B8.1结构体8.1.5结构体数组/15例struct{intnum;charname[20];charsex;intage;}stu[]={{……},{……},{……}};引用方式:结构体数组名[下标].成员名structstudent{intnum;charname[20];charsex;intage;}str[3];stu[1].age++;strcpy(stu[0].name,”ZhaoDa”);8.1结构体结构体数组的初始化结构体数组的引用/16structperson{charname[20];intcount;}leader[3]={“Li”,0,“Zhang”,0,”Wang“,0};main(){inti,j;charleader_name[20];
for(i=1;i<=10;i++){scanf("%s",leader_name);
for(j=0;j<3;j++) if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;}for(i=0;i<3;i++)printf("%5s:%d\n",leader[i].name,leader[i].count);}namecountLiZhangWang000例统计后选人选票8.1结构体/178.1结构体8.1.6结构体指针变量一个指针变量可以指向一个结构体数组元素(将该结构体数组的数组元素地址赋给此指针变量)。例struct{inta;floatb;}arr[3],*p;p=arr;此时p指向arr数组的第一个元素,“p=arr;”等价于“p=&arr[0];”。若执行“p++;”则此时指针变量p此时指向arr[1]。定义形式:struct
结构体名*结构体指针名;例structstudent*p;存放结构体变量在内存的起始地址numnamesexagestupstructstudent{intnum;charname[20];charsex;intage;}stu;structstudent*p=&stu;/18使用结构体指针变量引用成员形式指向运算符优先级:1结合方向:从左向右例intn;int*p=&n;*p=10;n=10structstudentstu1;structstudent*p=&stu1;stu1.num=101;(*p).num=1018.1结构体结构体指针名->成员名结构体变量名.成员名(*结构体指针名).成员名/198.1结构体例输出数组中各元素中各成员的值。structstudent{intnum;charname[20];charsex;intage;};structstudentstu[3]={{10101,"Zhang",'M',18},{10102,"Li",'M',19},{10103,"Wang",'F',20}};main(){structstudent*p;printf("No.Namesexage\n");for(p=stu;p<stu+3;p++)printf("%5d%-20s%2c4d\n",p->num,p->name,p->sex,p->age);}/208.1结构体10101"Zhang"'M'1810102"Li"'M'1910103"Wang"'F'20stu[0]stu[1]stu[2]PP’P”指针移动示意图:注意:①如果p的初值为stu,即指向第一个元素,则p+1后指向下一个元素的起始地址。请区别:
(++p)->num和(p++)->num②指针p已定义为指向structstudent类型的数据,它只能指向该结构体类型数据,而不能指向一元素的某一成员(即p的地址不能是成员的地址)。如下面的赋值是错误的:
p=&/218.1结构体8.1.7结构体与函数1、结构体变量作函数参数有时需要将一个结构体变量的值传递给另一个函数可以:
用结构体变量的成员作参数。用法和普通变量作实参是一样的,属“值传递”方式。形参与实参都用结构体变量直接将实参结构体变量的各个成员的值全部传递给形参的结构体变量。注意:实参和形参类型应当完全一致。/22structdata{inta,b,c;};main(){voidfunc(structdata);structdataarg;arg.a=27;arg.b=3;arg.c=arg.a+arg.b;printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);printf("CallFunc()....\n");
func(arg);printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);}voidfunc(structdataparm){printf("parm.a=%dparm.b=%dparm.c=%d\n",parm.a,parm.b,parm.c);printf("Process...\n");parm.a=18;parm.b=5;parm.c=parm.a*parm.b;printf("parm.a=%dparm.b=%dparm.c=%d\n",parm.a,parm.b,parm.c);printf("Return...\n");}8.1结构体arga:27b:3c:30(main)arga:27b:3c:30(main)(func)parma:27b:3c:30copyarga:27b:3c:30(main)(func)parma:18b:5c:90arga:27b:3c:30(main)/238.1结构体用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参。形参为指针变量,实参为结构体变量的地址或指向结构体变量的指针。2、结构体指针作函数参数/248.1结构体structdata{inta,b,c;};main(){voidfunc(structdata*parm);structdataarg;arg.a=27;arg.b=3;arg.c=arg.a+arg.b;printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);printf("CallFunc()....\n");
func(&arg);printf("arg.a=%darg.b=%darg.c=%d\n",arg.a,arg.b,arg.c);}voidfunc(structdata*parm){printf("parm->a=%dparm->b=%dparm->c=%d\n",parm->a,parm->b,parm->c);printf("Process...\n");parm->a=18;parm->b=5;parm->c=parm->a*parm->b;printf("parm->a=%dparm->b=%dparm->c=%d\n",parm->a,parm->b,parm->c);printf("Return...\n");}arga:27b:3c:30(main)arga:27b:3c:30(main)(func)parm****arga:18b:5c:90(main)(func)parm****arga:18b:5c:90(main)/258.1结构体例有一个结构体变量stu,内含学生学号、姓名和三门课的成绩。要求在main函数中赋值,在另一函数print中将它们打印输出。程序如下。#include"string.h"#defineformat"%d\n%s\n%f\n%f\n%f\n"structstudent{intnum;charname[20];floatscore[3];};main(){voidprint();structstudentstu;stu.num=12345;strcpy(,"LiPing");stu.score[0]=67.5;stu.score[1]=89;stu.score[2]=78.5;print(&stu);}voidprint(structstudent*p){printf(format,p->num,p->name,p->score[0],p->score[1],p->score[2]);printf("\n");}/268.1结构体值得指出的是,把一个完整的结构体变量作为参数传递,虽然合法,但要将全部成员值一个一个传递,既费时间又费空间,开销大,因此一般不采用。上例的print函数形参改用结构体变量后程序如下:注意:ANSIC允许用整个结构体作为函数的参数传递,但是必须保证实参与形参的类型相同。#include"string.h"#defineformat"%d\n%s\n%f\n%f\n%f\n"structstudent{intnum;charname[20];floatscore[3];};main(){voidprint();structstudentstu;stu.num=12345;strcpy(,"LiPing");stu.score[0]=67.5;stu.score[1]=89;stu.score[2]=78.5;print(stu);}voidprint(p)structstudentp;{printf(format,p.num,,p.score[0],p.score[1],p.score[2]);printf("\n");}/278.1结构体
ANSIC还允许函数返回结构体类型的值。设有一个structstudent类型,结构体变量定义如下:structstudentstud[30];若函数input()的功能是输入一个学生结构体数据,并将其返回给第i个学生记录stud[i],即:for(k=0;k<30;k++)stud[k]=input();3、返回结构体类型值的函数input()函数定义如下:structstudentinput(){intk;structstudentstud;scanf("%d",&stud.num);gets();for(k=0;k<3;k++)scanf("%f",&stud.score[k]);returnstud;}/288.2共用体8.2.1共用体类型声明结构体类型定义构造数据类型,也叫联合体用途:使几个不同类型的变量共占一段内存(相互覆盖)union共用体名{
类型标识符成员名;类型标识符成员名;
…………….};例uniondata{inti;charch;floatf;};fchi类型定义不分配内存/298.2共用体8.2.2共用体变量定义形式一:uniondata{inti;charch;floatf;}a,b;fchifchiab形式二:uniondata{inti;charch;floatf;};uniondataa,b,c,*p,d[3];形式三:union{inti;charch;floatf;}a,b,c;共用体变量定义分配内存,长度=最长成员所占字节数共用体变量任何时刻只有一个成员存在/308.2共用体8.2.3共用体变量的引用引用方式:结构体变量名.成员名引用规则不能引用共用体变量,只能引用其成员共用体变量中起作用的成员是最后一次存放的成员不能在定义共用体变量时初始化可以用一个共用体变量为另一个变量赋值共用体变量的地址和它的各个成员的地址相同共用体变量不能作函数参数,函数的返回值也不能是共用体类型共用体类型和结构体类型可以相互嵌套,共用体中成员可以为数组,甚至还可以定义共用体数组共用体指针名->成员名共用体变量名·成员名(*共用体指针名).成员名uniondata{inti;charch;floatf;};uniondataa,b,c,*p,d[3];a.ia.cha.fp->ip->chp->f(*p).i(*p).ch(*p).fd[0].id[0].chd[0].f例union{inti;charch;floatf;}a;a=1;()例a.i=1;a.ch=‘a’;a.f=1.5;printf(“%d”,a.i);(编译通过,运行结果不对)例union{inti;charch;floatf;}a={1,’a’,1.5};()例floatx;union{inti;charch;floatf;}a,b;a.i=1;a.ch=‘a’;a.f=1.5;b=a;()x=a.f;()/318.2共用体例将一个整数按字节输出main(){unionint_char{inti;charch[2];}x;x.i=24897;printf("i=%o\n",x.i);printf("ch0=%o,ch1=%o\nch0=%c,ch1=%c\n", x.ch[0],x.ch[1],x.ch[0],x.ch[1]);}0110000101000001低字节高字节0100000101100001ch[0]ch[1]运行结果:i=60501ch0=101,ch1=141ch0=A,ch1=a/32结构体与共用体区别:存储方式不同联系:两者可相互嵌套achkstructnode{charch[2];intk;}a;unionnode{charch[2];intk;}b;bchk变量的各成员同时存在任一时刻只有一个成员存在/338.3枚举类型8.3.1枚举类型的声明枚举类型定义枚举数据类型,指这种类型变量的取值只能限于事前已经一一列举出来的值的范围
enum枚举类型名{
枚举常量;;枚举常量;;
…………….};例enumweekday{sun,mon,tue,wed,thu,fri,sat};/348.3枚举类型8.3.2枚举类型变量的定义形式一:
enumweekday{sun,mon,tue,wed,thu,fri,sat}a,b;形式二:enumweekday{sun,mon,tue,wed,thu,fri,sat};enumweekdaya,b;形式三:
enum{sun,mon,tue,wed,thu,fri,sat}a,b;/358.3枚举类型说明:
enum是关键字,标识枚举类型,定义枚举类型时必须用enum开头。在定义枚举类型时,花括号中的枚举元素是常量,这些元素的名字是程序设计者自己指定的,命名规则与标识符相同。这些名字只是作为一个符号,以利于提高程序的可读性,并无其它固定的含义。枚举元素是常量,在C编译器中,按定义时的排列顺序取值0、1、2、...。定义枚举类型时,可在枚举数据时通过“=”号规定序号,并影响后面的枚举数据的序号,后继序号以此递增。枚举元素是常量,不是变量,可以将枚举常量赋给一个枚举变量,但不能对枚举元素赋值。但在定义枚举类型时,可以指定枚举常量的值枚举值可以作判断比较整型与枚举类型是不同的数据类型,不能直接赋值,但可以通过强制类型转换赋值枚举常量不是字符串不能用下面的方法输出字符串“sun”:printf("%s",sun); ()而应用检查的方法去处理:if(week1==sun)printf("sun");例week1=wed;printf("%d",week1);输出整数3enumstatus{copy=6,delete};则copy的序号为6,delete的序号为7。week2=sat; ()sun=0;mon=1; ()enumweekday{sun=7,mon=1,tue,wed,thu,fri,sat};tue、wed、...的值从mon的值顺序加1。如,tue=2/36例某口袋中有红、黄、蓝、白、黑五种颜色的球若干个,每次从口袋中取出三个球,问得到三种不同颜色的球有多少种取法,并输出每种组合结果。8.3枚举类型for(n=0,i=1;i<=5;i++)/*取第一个球*/for(j=1;j<=5;j++)/*取第二个球*/if(i!=j)/*第一个与第二个不同色*/{for(k=1;k<=5;k++)/*取第三个球*/if((k!=i)&&(k!=j)){n++;/*统计有多少种取法*/printf(″%d,%d,%d\n″,i,j,k);/*输出一种取法*/}}不用枚举类型:/378.3枚举类型采用枚举类型来描述数据。设用red表示红色球,yellow表示黄色球,blue表示蓝色球,white表示白色球,black表示黑色球。/38main(){enumcolor{red,yellow,blue,white,black};enumcolori,j,k,l;intn,m;for(n=0,i=red;i<=black;i++)for(j=red;j<=black;;j++)if(i!=j){for(k=red;k<=black;k++)if((k!=i)&&(k!=j)){n++;printf(″%4d″,n);for(m=1;m<=3;m++){switch(m){case1:l=i;berak;case2:l=j;berak;case3:l=k;berak;}switch(l)/*间接输出*/{casered:printf(″%8s″,″red″),break;caseyellow:printf(″%8s″,″yellow″);break;caseblue:printf(″%8s″),″blue″);break;casewhite:printf(″%8s″,″white″);break;;caseblack:printf(″%8s″,″black″);break;}}printf(″\n″);}}printf(″总的取法有%d种\n″,n);}/398.4用typedef定义类型8.4.1typedef的概念功能:用自定义名字为已有数据类型
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论