




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章结构体、联合体和枚举1本章主要内容结构体的说明和定义结构体成员的引用与结构体变量的初始化结构体数组结构体指针结构体在函数间的传递结构体指针型和结构体型函数结构体嵌套联合体枚举类型自定义类型位字段结构体2清华大学黄维通设计制作8.1结构体的说明和定义3清华大学黄维通设计制作结构体说明的格式:
struct结构体名{
结构体成员表;}8.1.2结构体的说明及结构体变量的定义structdate{intyear;intmonth;intday;intyearday;};
1.结构体的说明
5清华大学黄维通设计制作2结构体变量的定义(1)在结构体说明的同时定义结构体变量,例如:structexample{char*name;intage;}guo,zhang;
(2)直接定义结构体变量,例如:struct{char*name;intage;}guo,zhang未给出结构体名(3)把定义和说明分开,例如:structexample
{char*name;intage;};
structexampleguo,zhang;
结构体变量占用内存的大小可用sizeof()运算来求出6清华大学黄维通设计制作变量说明形式
struct
结构体名结构体变量名;注意:结构变量的存储类型概念、它的寿命、可见性及使用范围与普通变量、数组等完全一致。结构体变量说明必须在结构类型定义之后,二者也可同时进行。7清华大学黄维通设计制作引用结构体成员的一般形式如下:
结构体变量名.成员名
8.2.1结构体成员的引用成员名与程序中其他变量名可以相同,但代表不同的对象,为增强可读性,不提倡这样做structexample{longintid;charadd[100];}guo;各成员的引用:guo.idguo.add或guo.add[i]9清华大学黄维通设计制作
不能将一个结构体变量作为一个整体加以引用,而只能对结构体变量中各个成员进行引用如:printf(“…”,student1);(错误)对成员变量可以象普通变量一样进行各种运算成员地址与结构体地址都可以引用,如:scanf(“%d”,&student1.num);…它是成员地址引用printf(“%d”,&student1);…它是结构体地址引用
赋值时,与数组类似,只能当结构体变量为全局变量及静态变量时,可以赋值10清华大学黄维通设计制作结构体变量初始化的一般形式如下:struct结构体名
结构体变量名={初始数据};structdate{intyear;
intmonth;
intday;
charmonthname[4];};structdatedate1={2003,10,1,”Sept”};8.2.2结构体变量的初始化11清华大学黄维通设计制作/*******结构体字节长度的计算******/structregist {charyour_name[66];intyour_age;}wang;main(){printf("regist:%d\n",sizeof(structregist));printf("wang:%d\n",sizeof(wang));}13清华大学黄维通设计制作8.3结构体数组
14清华大学黄维通设计制作1结构体数组的定义(也有类似三种方式)
[存储类型]struct结构体名
结构体数组名[元素个数][,结构体数组名[元素个数],…];
8.3.1结构体数组的定义及初始化
2结构体数组的初始化
structkeykeytab[]={{”shift”,0},
{”del”,0},
…{”pause”,0}};
15清华大学黄维通设计制作for(i=0;i<MAXIMUM;i++){printf("name?");gets(stu[i].name);printf(“sex?”);gets(str);
stu[i].sex=str[0];printf("age?");gets(str);stu[i].age=atoi(str);printf("tel?");gets(stu[i].tel);printf("add?");gets(stu[i].add);}for(i=0;i<MAXIMUM;i++){printf("%s%d",stu[i].name,stu[i].age); printf("%c%s%s",stu[i].sex,stu[i].tel,stu[i].add);
}}}17清华大学黄维通设计制作8.4结构体指针18清华大学黄维通设计制作8.4.1结构体指针及其定义结构体指针的定义类似格式如下:[存储类型]struct结构体名*结构体指针名;例如:staticstructexample*pexample;
存放结构体首地址结构指针的运算按照C语言的地址运算原则进行19清华大学黄维通设计制作/*例***指向结构体数组的指针及其应用**/#include<stdio.h>#include<conio.h>structdate{intyear;intmonth;intday; };structscore{inttc; intvb; intdelphi;floataverage; };staticstructstudent{charname[10]; intnumber;charsex;structdateb;structscorer;}s[2];21清华大学黄维通设计制作main(){inti;floatt;charch[20];structstudent*p;p=s;
for(i=0;i<2;i++,p++){printf("Names:");gets(p->name);printf("Numberd:");scanf("%d",&p->number);
printf("Sexc:");gets(ch);p->sex=ch[0];
printf("year/month/day:");scanf("%d%d%d",&p->b.year,&s[i].b.month,&(*p).b.day);
t=0;
printf("tc/vb/delphi:");scanf("%d%d%d",&s[i].r.tc,&s[i].r.vb,&s[i].r.delphi);
t=s[i].r.tc+s[i].r.vb+s[i].r.delphi;s[i].r.average=t/3.0;}printf("\nNameNumberSexYearMonthDaytcvbdelphiaverage\n");for(i=0;i<2;i++){printf("%s%d%c",s[i].name,s[i].number,s[i].sex);printf("%d%d%d",s[i].b.year,s[i].b.month,s[i].b.day);
printf("%d%d%d%f\n",s[i].r.tc,s[i].r.vb,s[i].r.delphi,s[i].r.average);}}使用char*name时,不能用此语句22清华大学黄维通设计制作1用地址复制方式传递结构体变量
【例】用地址复制方式传递结构体变量
给出年月日计算它是该年的第几天#include"stdio.h"structdate{ intyear; intmonth; intday; intyearday;};8.5结构体在函数间的传递23清华大学黄维通设计制作main(){structdated1;printf(“Eenteryear,month,day:");scanf("%d%d%d",&d1.year, &d1.month,&d1.day);days(&d1);printf(“是第%d天",d1.yearday);}25清华大学黄维通设计制作【例】建立和显示学生成绩册#include"stdio.h"#include"stdlib.h"#defineMAXIMUM300structstud{charid[6];charname[30];intscore;};input(structstud*sp){charstr[10];printf(“学号:”);gets(sp->id);printf("姓名:");gets(sp->name);if(sp->name[0]==‘\0’)return(0);
printf("成绩:");gets(str);sp->score=atoi(str);return(1);}2结构体数组在函数间的传递
26清华大学黄维通设计制作
结构体指针型函数定义的一般形式为:
struct结构体名*函数名([形参表])[形参说明;]{内部数据说明语句;
执行语句;};
其说明形式为:struct结构体名*函数名();
8.6.1结构体指针型函数
29清华大学黄维通设计制作【例】假设有一个电话号码表,给定一个用户id,找出其对应信息。#include"stdio.h"#defineNull0structdata{inttel;intid;charname[30];charadd[100];};structdataper[500];
30清华大学黄维通设计制作personlist() //建立电话号码表函数{inti;for(i=0;i<500;i++){scanf("%d",&per[i].tel);scanf("%s%s",per[i].name,per[i].add);per[i].id=i;if(per[i].tel==Null)break;}}structdata*found(intn)//给定id查信息
{inti;for(i=0;per[i].tel!=Null;i++)if(per[i].id==n)break;return(&per[i]);}31清华大学黄维通设计制作voidmain(){intnumber; structdata*sp;personlist();printf(“\n请输入要查找信息的id:");scanf("%d",&number);if(number==Null)break;sp=found(number);if(sp->id!=Null){printf("%d",sp->tel);printf("%s%s",sp->name,sp->add);}elseprintf(“notfound!\n");}建立电话号码表给定id查信息返回指针32清华大学黄维通设计制作
结构体型函数定义的一般形式如下:
struct结构体名
函数名([形参表])[形参说明;]{
内部数据说明语句;
执行语句;};
结构体型函数说明的一般形式如下:
struct结构体名
函数名();
8.6.2结构体型函数
33清华大学黄维通设计制作【例】返回值为结构体变量的函数#include<string.h>#include"stdio.h"structdata{chars[30];intn;floatx;};structdataexample(){structdataemp;strcpy(emp.s,“Anexample!");emp.n=68; emp.x=213.52;printf("%s%d%f\n",emp.s,emp.n,emp.x);return(emp);}voidmain(){structdataredata;printf("\n运行函数:\n");redata=example();
printf("%s%d%f\n",redata.s,redata.n,redata.x);
}34清华大学黄维通设计制作/*******结构型指针型函数,输入学号,查找相应学生的数据*/#defineNULL0structstudent{longintnum;char*name;floatscore;}stu[]={{990001,"Li",90},{990002,"Zhang",80},{990003,"Zhao",70},{0,0,0,}};main(){longintnumber;structstudent*result,*find();/*定义结构指针及结构指针函数*/printf("Enteranumber:");scanf("%ld",&number);result=find(number);/*调用函数开始查找,结构find是指针型函数,*/ /*执行此句,将结构体变量的地址传给型参*/if(result->num!=NULL){ printf("number:%ld\n",result->num); printf("color:%s\n",result->name); printf("type:%f\n",result->score);}else printf("Notfound\n");}35清华大学黄维通设计制作structstudent*find(n)/*查找,返回找到的结构体的首地址*/longintn;{inti;for(i=0;stu[i].num!=NULL;i++) /*寻找stu[0]至stu[3],其中stu[3]={0,0,0}*/if(stu[i].num==n)break; /*找到了,若没找到,则返回stu[i].num=0,*/ /*返回后,经if比较,执行else语句*/return(&stu[i]);/*注意不能写成&stu[i].num*/}36清华大学黄维通设计制作structdate{intyear; intmonth;intday;};8.7结构体嵌套
structperson{charid[6];charname[30];charsex;
structdatebirthday;}stu;Birthday具有monthday和year三个成员这就是结构体嵌套参加运算和操作的只能是最内层结构的成员项内层结构成员的引用形式:结构变量名.外层成员名.内层成员名如:stu.birthday.month37清华大学黄维通设计制作structexample{intdata;structexample*next;};
datadatadatadata38清华大学黄维通设计制作structadd
{intpost;charaddr[100];chartel[8];};structperson{charname[30];
structaddwadd;structaddhadd;};structpersonLi;8.7.2嵌套结构体类型变量的引用
LLi.hadd.postLi.wadd.postLi.wadd.addr
structperson*pman;pman–>namepman–>wadd.postpman–>wadd.tel39清华大学黄维通设计制作【例】用嵌套型结构体变量处理通讯录#include<stdio.h>#include<stdlib.h>#defineMAXIMUM100structaddress {char*postcode;charaddr[100];chartel[8];};structperson {charname[30];structaddresswadd;structaddresshadd;}grade[MAXIMUM];8.7.3结构体嵌套应用举例
40清华大学黄维通设计制作voidinputdata(){inti;chars[10];for(i=0;i<100;i++){printf("姓名:");gets(grade[i].name);if(grade[i].name[0]=='\0')return;printf(“邮编1”);gets(grade[i].wadd.postcode);printf(“工作地址”);gets(grade[i].wadd.addr);printf(“电话”);gets(grade[i].wadd.tel);printf(“邮编2”);gets(grade[i].hadd.postcode);printf(“家庭地址:”);gets(grade[i].hadd.addr);return;}}41清华大学黄维通设计制作voidmain(){inti;for(i=0;i<MAXIMUM;i++){if(grade[i].name[0]=='\0')
break;printf("\n%s",grade[i].name);
printf("%d%s%s",grade[i].wadd.postcode,grade[i].wadd.addr,grade[i].wadd.tel);
printf("%d%s%s",grade[i].hadd.postcode,grade[i].hadd.addr,grade[i].hadd.tel);}}42清华大学黄维通设计制作联合体是一种类似于结构体的构造型数据类型,它准许不同类型和不同长度的数据共享同一块存储空间8.8联合体43清华大学黄维通设计制作1联合体的说明联合体的说明与结构体类似。union联合体名{类型标识符成员名1;…类型标识符成员名n;};8.8.1联合体的说明及联合体变量的定义
unionarea{charc_data;shorts_data;longl_data;};共用体的定义与结构体定义很类似,只是关键词的不同struct<----->union既然几种不同的变量占用同一个内存段,那么,变量所占的内存长度应为最长的成员长度44清华大学黄维通设计制作2联合体变量的定义
(1)说明与定义分开:
union联合体名{类型标识符
成员名1;…
类型标识符
成员名n;
};union联合体名
变量名表;
例如:
unionuniontype{inta; longd;
};unionuniontypemy_data;
(2)定义与说明合在一起:union联合体名{数据类型标识符
成员名1;
…数据类型标识符
成员名n;
}变量名表;例如:unionuniontype{inta;longd;
}my_data;
(3)定义和说明合在一起,但缺省联合体名:union{数据类型标识符
成员名1;…
数据类型标识符
成员名n;
}联合体变量名表;例如:union{inta;longd;}my_data;
45清华大学黄维通设计制作结构体与联合体可以互相嵌套,例如:unionuniontype{inti;
floatf;
};structstructtype{shorts;
longl;
};structsutype{charc;
unionuniontypeu;
};unionustype{inti;
structstructtypest;};46清华大学黄维通设计制作3联合体变量成员的引用
联合体变量成员的引用类似结构体变量,也是利用运算符“–>”和“.”。例如:unionuniontype{inti;charc;
}my_data;unionuniontype*p;
p=&my_data;
下列引用都是合法的:my_data.i,my_data.c,p->i,p–>c47清华大学黄维通设计制作两个具有相同联合体类型的联合体变量可以互相赋值联合体变量可以作为参数传递给被调用函数联合体变量可以作为函数的返回值,从被调用函数返回调用函数同一内存段可用来存放几种不同类型的成员,但每一瞬间只有一个成员不能对共用体变量表列赋值,这一点与结构体不一样,如:
union{inti;charch;floatb;}a={a,‘a’,1.5};这是不对的8.8.2使用联合体变量应注意的问题
48清华大学黄维通设计制作【例】建立教师和学生登记表,其中包括识别号、姓名、身份和职称。若身份是“student”时,则职称一栏填年级;若身份是“teacher”时,则职称栏填职称。#include"stdio.h"#include"string.h"structpersontype{intid;charname[30]; charjob[10];
union{intgrade;charposition[10];}level;}person[5];联合体嵌套在结构体的定义中49清华大学黄维通设计制作voidmain(){intn,i;
printf("\nPersonalInformation(ID,姓名,身份,年级或职称):\n“);for(i=0;i<5;i++)//输入数据{scanf("%d%s%s",&person[i].id,person[i].name,person[i].job);
if(strcmp(person[i].job,"student"))scanf("%d",&person[i].level.grade);elseif(strcmp(person[i].job,"teacher"))scanf("%s",person[i].level.position);elseprintf("输入错误!\n");}50清华大学黄维通设计制作printf("IDnamejobgrade/position\n");for(i=0;i<5;i++) //输出数据{if(strcmp(person[i].job,"student"))printf("%d%s%s%d\n",person[i].id,person[i].name,person[i].job,person[i].level.grade);elseprintf("%d%s%s%s\n",person[i].id,person[i].name,person[i].job,person[i].level.position);}}51清华大学黄维通设计制作8.9枚举类型
52清华大学黄维通设计制作1枚举的概念枚举类型也是一种数据类型。对那些只可能取有限的某几种值的数据,可以把它定义为枚举类型数据8.9.1枚举类型数据的概念及其定义
如果某些变量只有几种可能,如:星期一、星期二、……星期日性别及特定范围的概念可以通过枚举法将变量一一列出,在这种情况下可以使用枚举类型变量53清华大学黄维通设计制作2枚举类型数据的说明
枚举类型说明的一般形式为:enum枚举名{元素名1,元素名2,…,元素名n};例如:
enummonth{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};//该枚举类型只准许取12种值
enumweekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat};
//该枚举类型只准许取7种值
54清华大学黄维通设计制作3枚举型变量的定义枚举型变量的定义也有三种方式:说明与定义合一
,如:
enumweekday{Sun,Mon,Tue}day;
(2)用无名枚举类型,如:
enum{Sun,Mon,Tue}day;(3)说明与定义分开,如:
enumweekday{Sun,Mon,Tue};
enumweekdayday;55清华大学黄维通设计制作为正确使用枚举型变量,应注意:枚举类型说明中的元素以常量名处理,不是变量名,这些常量依序分别为0、1、…、n-1。例如:
enumweekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat}workday;上述枚举元素的值分别为0、1、2、3、4、5、6。8.9.2枚举型变量的使用
枚举元素是常量,不是变量,不能对它赋值,如:sun=0;mon=1;etc.56清华大学黄维通设计制作枚举元素的值也可在定义时指定。
enumweekday{Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat}workday;
对于没有指定值的元素,其取值原则仍按所处的顺序取,故:
Tue是2,Wed是3,…,Sat是6。
可用枚举变量进行判断或比较操作
enumflag{true,false}my_flag;
…if(my_flag==true)
57清华大学黄维通设计制作一个整数不能直接赋给枚举变量,要先进行强制类型转换才能赋值。如:
workday=6;是错误的。而:
workday=(enumweekday)6;
是正确的,它相当于
workday=Sat;58清华大学黄维通设计制作/*******三种颜色取不同两种排序,有几种方式?******/main(){enumcolor{red,yellow,blue};enumcolori,j;intn=0;for(i=red;i<=blue;i++)
{ for(j=red;j<=blue;j++) if(j!=i)
{n=n+1; printf("%-4d",n);
switch(i) { casered:printf("%-10s","red");break; caseyellow:printf("%-10s","yellow");break; caseblue:printf("%-10s","blue");break; default:break; }
switch(j) { casered:printf("%-10s","red");break; caseyellow:printf("%-10s","yellow");break; caseblue:printf("%-10s","blue");break; default:break; } printf("\n"); }}printf("ntotal:%5d\n",n);}结果:1 red yellow2 red blue3 yellow red4 yellow blue5 blue red6 blue yellown total: 659清华大学黄维通设计制作/***分别输入一周中的每天工作时间,并输出总的工资**///周日的工资为120RMB/h,周六为100RMB/h,其他时间80RMB/h#include<stdio.h>voidmain(){enumweek{SUN,MON,TUE,WED,THR,FRI,SAT};enumweekday;inttotal,pay,hour;total=0;printf("PleaseenteryourworkinghoursfromSUNtoSAT\n");for(day=SUN;day<=SAT;day++){scanf("%d",&hour);switch(day){caseSUN:pay=hour*120;break;caseSAT:pay=hour*100;break;default:pay=hour*80;break;/*fromMONtoFRI*/}total+=pay;}printf("Yourtotalpayis:%d",total);}60清华大学黄维通设计制作【例】某小学举行竞赛活动,共有5个项目,每人只能选其中的3项,编写程序,测出每个学生可能的选择方案。设这5个项目分别称p1、p2、
…
、p5。故可用如下形式的枚举型表示它:enumgroup{p1,p2,p3,p4,p5};
用get1、get2和get3表示一种选择方案中的3个选项。并且这3个选项不能重复,即:get1!=get2!=get3#include"stdio.h"main(){enumgroup{p1,p2,p3,p4,p5};enumgroupget1,get2,get3,pri;intn=0,loop;for(get1=p1;get1<=p5;get1++)for(get2=get1+1;get2<=p5;get2++)61清华大学黄维通设计制作if(get1!=get2){for(get3=get2+1;get3<=p5;get3++)if((get3!=get1)&&(get3!=get2){n++; //输出一种选择方案printf("%-4d",n);
for(loop=1;loop<=3;loop++){
switch(loop){case1:pri=get1;break;case2:pri=get2;break;case3:pri=get3;break;default:break;}
switch(pri){casep1:printf("%-10s","p1");break;casep2:printf("%-10s","p2");break;casep3:printf("%-10s","p3");break;casep4:printf("%-10s","p4");break;casep5:printf("%-10s","p5");break;default:break;}}printf("\n");}}printf("\ntotal=%5d",n);}62清华大学黄维通设计制作8.10自定义类型63清华大学黄维通设计制作类型定义:给已存在的数据类型重命名
类型定义的一般形式为:typedefoldtypenewtype;
8.10.1自定义类型及其表示形式
例如:typedefintINTEGER;就为int重新命名了一个新名字,于是inta,b;
与INTEGERa,b;
是完全等价的两个变量定义语句。
64清华大学黄维通设计制作增强程序的可读性和可移植性可以自定义结构体,如:typedefstructstudent{char*name;intnumber;}STU;
STUstu1;
那么,stu1就拥有name和number两个成员
8.10.2自定义类型的优点
65清华大学黄维通设计制作有了上述概念之后,还可再进一步:typedefintNUM[10]定义NUM为整型数组类型NUMn;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 自己在家安全教育
- Unit 3 Section B 2a~2c 教学设计2023-2024学年人教版英语七年级下册
- 《卢沟谣》(教学设计)-2024-2025学年五年级上册人教版(2012)音乐
- 妊娠合并癫痫护理查房
- Unit 7 Lesson2 Is this your brother 说课(教学设计)-2024-2025学年鲁科版(五四学制)(三起)(2024)英语三年级上册
- 销售业务合作协议(简单)7篇
- 《卖报歌》(教学设计)-2024-2025学年三年级上册湘艺版(2012)音乐
- 七年级道德与法治下册 第一单元 青春时光 第二课 青春的心弦 第一框 男生女生教学设计 新人教版
- 2《我能行》(教案)-大象版心理健康五年级
- 美院国画山水技法课件
- 2025年福建省南平事业单位招考笔试高频重点提升(共500题)附带答案详解
- 2024-2025学年广东省深圳市南山区监测数学三年级第一学期期末学业水平测试试题含解析
- 星际分子光谱分析学的研究方法探究系列如下-洞察分析
- 儿童春季常见病及预防
- 《中华人民共和国学前教育法》专题培训
- 2024年微生物在化妆品中的作用及其重要性
- 放射科报告质量问题整改措施
- 黄芪苗收购合同
- 焦虑症课件完整版
- 移动机器人机械臂的结构设计论文
- 手术患者围手术期的管理
评论
0/150
提交评论