结构体、共用体与枚举类型.ppt

上传人:zhu****ei 文档编号:3523066 上传时间:2019-12-17 格式:PPT 页数:54 大小:668.50KB
返回 下载 相关 举报
结构体、共用体与枚举类型.ppt_第1页
第1页 / 共54页
结构体、共用体与枚举类型.ppt_第2页
第2页 / 共54页
结构体、共用体与枚举类型.ppt_第3页
第3页 / 共54页
点击查看更多>>
资源描述
第8章结构体、共用体与枚举类型,本章要求:,理解结构体类型的概念,掌握结构体变量的定义和使用;掌握结构体数组、结构体指针的定义和使用;理解链表的概念,掌握动态链表的常见操作;理解共用体的概念,掌握共用体变量的定义和使用。,本章重点:动态链表的常见操作,本章难点:动态链表的常见操作,第8章结构体、共用体与枚举类型,8.1结构体类型与结构体变量8.2结构体数组8.3结构体与函数8.4动态数据结构链表8.5共用体8.6枚举类型8.7自定义类型标识符(typedef),第8章结构体、共用体与枚举类型,8.1结构体C语言提供一种能集中不同数据类型于一体的数据类型结构体类型。结构体类型的变量可以拥有不同数据类型的成员,是不同数据类型成员的集合。结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体自定义数据类型,8.1结构体类型与结构体变量,8.1.1什么是结构体类型,第4章学习的数组是一种简单构造类型数据,数组中的各元素是属于同一个类型的。但在实际处理的问题中,常会遇到这样一类数据,它由多个属性各不相同的数据项组成,各个数据项用来描述一个共同的对象。结构体(structure)是一种数据类型。C语言本身没有提供具体的结构类型,但提供了说明结构体类型的方法。,8.1.2结构体的声明,声明结构体类型的一般形式:,struct结构体名结构成员1;结构成员2;结构成员n;,8.1结构体类型与结构体变量,例如:定义一个可描述学生基本情况的结构体类型如下:structstudentintnum;charname20;charsex;intage;floatscore;,8.1结构体类型与结构体变量,例structstudentintnum;charname20;charsex;intage;floatscore;structstudentstu1,stu2;,8.1.3结构体变量的定义定义好一个结构体类型后(也可以理解为是我们用户自己定义的类型),我们可以将其看作是和int、char、float等数据类型一样的一个新的数据类型,可以用它定义变量,通过变量对结构体中各成员的数据进行处理。1.先定义结构体类型,再定义结构体变量一般形式:,struct结构体名类型标识符成员名;类型标识符成员名;.;struct结构体名变量名表列;,8.1结构体类型与结构体变量,2.定义结构体类型的同时定义结构体变量一般形式:,struct结构体名类型标识符成员名;类型标识符成员名;.变量名表列;,例structstudentintnum;charname20;charsex;intage;floatscore;stu1,stu2;,8.1.3结构体变量的定义,3.直接定义结构体变量一般形式:,struct类型标识符成员名;类型标识符成员名;.变量名表列;,例structintnum;charname20;charsex;intage;floatscore;stu1,stu2;,8.1.3结构体变量的定义,8.1.3结构体变量的引用,1结构体变量的引用格式结构体变量名.成员名其中:“.”是成员运算符,它在所有的运算符中优先级最高。例如,对上小节定义的学生情况结构体变量stu1变量进行赋值:stu1.num=10001;strcpy(stu1.name,”zhang”);stu1.sex=M;stu1.age=19;stu1.score=88;不能把结构变量作为整体进行输入输出:scanf(“%d%s%c%d%f”,stu1);正确的引用方式可以是:gets(stu1.name);scanf(“%d%c%d%f”,2结构体嵌套时逐级引用,structdateintmonth;intday;intyear;,structpersoncharname20;charsex;structdatebirthday;,若有定义:structpersonperson1;这时可以这样访问person1中的成员month:person1.birthday.month,8.1.3结构体变量的引用,8.1.3结构体变量的引用,33.同类型结构体变量间的整体赋值,结构体变量可以通过整体赋值,将一个结构体变量中的所有数据,赋给另一个结构体类型相同的结构体变量中对应的数据成员。,例8-1建立一个学生的基本情况表,然后将其打印输出。程序如下:,#include#includemain()structstudentintnum;charname20;charsex;intage;floatscore;stu1,stu2;stu1.num=10001;strcpy(stu1.name,zhang);stu1.sex=M;stu1.age=19;stu1.score=88;stu2=stu1;printf(stu1:%d,%s,%c,%d,%6.2fn,stu1.num,stu1.name,stu1.sex,stu1.age,stu1.score);printf(stu2:%d,%s,%c,%d,%6.2fn,stu2.num,stu2.name,stu2.sex,stu2.age,stu2.score);,程序输出结果如下:stu1:10001,zhang,M,19,88.00stu2:10001,zhang,M,19,88.00,struct结构体名类型标识符成员名;类型标识符成员名;.结构体变量=初始数据;,例structstudentintnum;charname20;charsex;intage;floatscore;stu1=10001,zhang,M,19,88;,8.1.4结构体变量的初始化,形式:,8.1.6指向结构体的指针,指向结构体变量的指针的值是该结构体变量所分配的存储区域的首地址。,结构指针变量的定义,例:structstudentintnum;charname20;charsex;intage;floatscore;stu1=10001,”zhang”,M,19,88;structstudent*p=stu1;,8.1.6指向结构体的指针,通过指针访问结构体变量的成员,结构变量中简单成员的引用形式有下面三种:结构变量名.成员名(名字引用);结构指针-成员名(指针引用);(*结构指针).成员名(将指针转化为名字引用);,例:若有定义:structstudent*p,stu1;且p=则要访问stu1的成员(如age)有下三种方式:stu1.age或p-age或(*p).age,8.2结构体数组,8.1.1结构体数组的定义,结构体数组的定义方式同结构体变量一样,也有3种方法,只需把结构体变量换成结构体数组即可。,例:structstudentintnum;charname20;charsex;intage;floatscore;structstudentstu10;,结构体数组的初始化,与通常数组的初始化类似。例如:structstudentintnum;charname20;charsex;intage;floatscore;stu4=10001,Zhang,M,19,80,10002,Li,M,18,78,10003,He,F,20,92.5,10004,Cheng,F,18,70;,结构体数组的初始化,8.2结构体数组,结构体数组引用方式:结构体数组名下标.成员名例:stu1.age+,8.2.2结构体数组与指针,指向结构体数组的指针的值是该结构体数组所分配的存储区域的首地址。,例:structstudentintnum;charname20;charsex;intage;floatscore;structstudent*p;structstudentstu10;p=stu;,p就是指向结构体数组stu的指针(如右图所示),8.2.3结构体数组的应用实例,例8-3,#defineN10#include#includestructstudent/*定义student结构体类型*/intnum;charname20;floatscore3;main()inti,j;structstudentstuN;for(i=0;iname);printf(%6.1f,%6.1f,%6.1fn,p-score0,p-score1,p-score2);,8.3结构体与函数,结构体类型的变量可以作函数的形参,调用时C直接把同类型结构体实参变量的各个数据成员的值全部复制给形参的结构体变量。为了提高效率和通用性,可以用指向结构体变量(或数组)的指针作为函数的形参。函数也可以返回结构体类型数据到主调函数中。,8.3.1结构体变量作函数参数,例8-5在例8-3中,10名学生的信息输出改为通过调用print函数完成。,voidprint(structstudentstu)printf(%d,%s,%6.1f,%6.1f,%6.1fn,stu.num,stu.name,stu.score0,stu.score1,stu.score2);,#defineN10#include#includestructstudent;main()inti,j;structstudentstuN;voidprint(structstudentstu);for(i=0;inext=P1,实现将新申请的结点插入到链表尾,使之成为新的尾结点。(2)malloc函数开辟第一个结点,并使head和p2都指向它。head=p2=(structstudent*)malloc(sizeof(structstudent);/*申请一个新结点的空间*/scanf(%d%f,/*读入数据*/,8.4.5动态链表的建立,(3)再用malloc函数开辟另一个结点并使p1指向它,接着输入该结点的数据,并与上一结点相连,且使p2指向新建立的结点。建立新结点:p1=(structstudent*)malloc(sizeof(structstudent);scanf(%d%f,如图8-6(c)所示:,8-6(a),8-6(b),8-6(c),重复执行第(3)步,可以建立第三个结点,并使第三个结点和第二个结点链接(p2-next=p1;),依次创建后面的结点,直到所有的结点建立完毕。(4)为末结点的指针域赋值NULL(p2-next=NULL;),8.4.5动态链表的建立,例8-7建立有n个student类型结点的链表,n的值从键盘输入,再输出链表。,#defineNULL0#defineLENsizeof(structstudent)#include#include/*定义结点*/structstudentintnum;floatscore;structstudent*next;/*main函数中,分别调用create和print函数建立和输出链表*/voidmain()intn;structstudent*head;structstudentcreate(intn);/*函数声明*/voidprint(structstudent*head);/*函数声明*/printf(pleaseinputnn);scanf(%d,/*create(intn)函数:创建一个具有头结点的单链表*/*形参n值:创建链表的结点数*/*返回值:返回单链表的头指针*/structstudent*create(intn)inti;structstudent*head=NULL,*p1,*p2;head=p2=(structstudent*)malloc(LEN);/*申请一个新结点的空间*/scanf(%d%f,例8-7建立有n个student类型结点的链表,n的值从键盘输入,再输出链表。,/*voidprint(structstudent*head)为链表输出函数*/*形参head为要输出链表的头指针*/voidprint(structstudent*head)structstudent*p;p=head;while(p!=NULL)printf(%d,%6.1fn,p-num,p-score);p=p-next;/*移动指针*/,例8-7建立有n个student类型结点的链表,n的值从键盘输入,再输出链表。,8.4.6链表的删除操作,下面讨论在结点类型为student的链表中删除num域为某个值的结点的主要操作步骤(链表结点为structstudent类型数据结构):设三个指针变量:head、p1、p2,它们都是用来指向structstudent类型数据的,head指向链表头,若head=NULL,则链表为空,没有可删除结点。查找要删除的结点,使p1指向它,p2指向p1的前一结点(前驱)。有两种情况:删除首结点和其它结点。,(1)删除首结点使p1指向第一个结点,用以下语句实现删除首结点操作。p1=head;head=p1-next;free(p1);,8.4.6链表的删除操作,(2)删除其它结点删除链表的中间结点通过将下一结点地址赋给前一结点地址来实现,也即将要删除的p1结点的后继地址,放入前一结点p2的地址域(p2-next=p1-next;),同时释放p1结点。,/*该函数的功能是从表头指针为head的链表中删除num域的值与形参num相等的结点,释放该结点的存储空间,返回该链表的表头指针。*/,structstudent*delete(structstudent*head,intnum)structstudent*p1,*p2;if(head=NULL)printf(listnull!n);elsep1=head;while(p1!=NULL,8.4.6链表的删除操作,8.4.7链表的插入操作,下面讨论在结点类型为student的链表中插入一个新生结点的主要操作步骤(链表结点为structstudent类型数据结构):先设四个指针变量head、p0、p1、p2:head:要插入链表的头指针。P0:指向要插入的结点。P1:指向当前结点,首先使p1指向头结点(p1=head)。P2:指向前一结点(即P1原来指向的结点)。首先查找插入的位置,应插入的位置:p1之前,p2之后。在链表中,各结点按成员score(成绩)由小到大顺序存放,从第一个结点开始,把待插入结点p0-score与每一个结点p1-score比较,若(p0-score)(p1-score),则p1移到下一个结点(p1=p1-next),同时,p2也移到下一个位置(p2=p1)。,(1)原链表为空表即head=NULL时,用以下语句实现插入操作:head=p0;p0-next=NULL;p0是该链表惟一一个结点。(2)在头结点之前插入当p0-scorescore时,若p1=head,表示插入结点在头结点之前。用以下语句实现插入操作:head=p0;p0-next=p1;,8.4.7链表的插入操作,插入前,插入后,8.4.7链表的插入操作,(3)在非头结点之前,非尾节点之后插入当p0-scorescore,且p1head时,表示在在非头结点之前,非尾节点之后(中间结点)插入结点,用以下语句实现插入操作:p2-next=p0;p0-next=p1;,插入前,插入后,8.4.7链表的插入操作,(4)尾节点之后插入当p0-scorep1-score时,表示在尾节点之后插入结点,用以下语句实现插入操作:p1-next=p0;p0-next=NULL;,插入前,插入后,函数insert的功能是:在一个有序链表中插入一个结点。,在链表head中,插入stud结点,并返回新链表的表头structstudent*insert(structstudent*head,structstudent*stud)structstudent*p0,*p1,*p2;p1=head;p0=stud;if(head=NULL)/*原链表是空表*/head=p0;p0-next=NULL;else/*while循环查找待插入的位置*/while(p0-scorep1-score),union共用体名类型标识符成员名;类型标识符成员名;.;,例uniondatainti;floatf;charch;,1.共用体类型定义定义形式:,构造数据类型,也叫联合体用途:使几个不同类型的变量共占一段内存(相互覆盖),8.5共用体,形式一:uniondatainti;charch;floatf;a,b;,形式二:uniondatainti;charch;floatf;uniondataa,b,c;,形式三:unioninti;charch;floatf;a,b,c;,2.共用体变量的定义,8.5共用体,共用体变量定义分配内存长度=最长成员所占字节数,8.5共用体,共用变量的引用与结构变量一样,也只能逐个引用共用变量的成员。例如,访问共用变量un1各成员的格式为:un1.i、un1.ch、un1.f。,对共用体变量的使用需要注意如下几个问题:(1)系统采用覆盖技术,实现共用变量各成员的内存共享,所以在某一时刻,存放的和起作用的是最后一次存入的成员值。(2)由于所有成员共享同一内存空间,故共用变量与其各成员的地址相同。(3)不能对共用变量进行初始化(注意:结构变量可以);也不能将共用变量作为函数参数,以及使函数返回一个共用数据,但可以使用指向共用变量的指针。(4)共用类型可以出现在结构类型定义中,反之亦然。,例8-9,8.5共用体,假设一个学生的信息表中包括学号、姓名和一门课的成绩。而成绩通常又可采用两种表示方法:一种是五分制,采用的是整数形式;另一种是百分制,采用的是浮点数形式,现要求编一程序,输入一个学生的信息并显示出来。程序如下:#includestructstu_scoreintnum;charname20;inttype;/*type值为0时五分制,type值为1时百分制*/unionmixedintiscore;/*五分制*/floatfscore;/*百分制*/score;,8.5共用体,main()structstu_scorestud1;printf(pleaseinputnum,name,type:n);scanf(%d%s%d,8.6枚举类型,1枚举类型的定义enum枚举类型名取值表;例如,enumweekdaysSun,Mon,Tue,Wed,Thu,Fri,Sat;声明了一个枚举类型enumweekdays,可以用此类型来定义变量。枚举变量的定义(与结构变量类似)(1)间接定义:先声明类型,再定义变量。例如,enumweekdaysworkday;(2)直接定义:声明类型类型的同时直接定义变量。例如,enumweekdaysSun,Mon,Tue,Wed,Thu,Fri,Satworkday;,说明(1)枚举型仅适应于取值有限的数据。例如,根据现行的历法规定,周天,年个月。(2)取值表中的值称为枚举元素,枚举元素是常量。在编译器中,按定义的顺序取值0、1、2、.。所以枚举元素可以进行比较,比较规则是:序号大者为大!例如,上例中的Sun=0、Mon=1、Sat=6,所以MonSun、Sat最大。(3)枚举元素的值也是可以人为改变的:在定义时由程序指定。例如,如果enumweekdaysSun=,Mon,Tue,Wed,Thu,Fri,Sat;则Sun=,Mon=,从Tue=2开始,依次增。,8.6枚举类型,例8-10,#includemain()enumweekdayssun,mon,tue,wed,thu,fri,satdate;inti;printf(pleaseinputthedate(1-30):);scanf(%d,8.6枚举类型,8.7typedef的使用,功能:用自定义名字为已有数据类型命名类型定义简单形式:typedeftypename;,例:typedefintINTEGER;typedeffloatREAL;定义新数据类型INTEGER,它代表已有数据类型int。定义新数据类型REAL,它代表已有数据类型float。,说明:(1)用typedef只是给已有类型增加个别名,并不能创造个新的类型。就如同人一样,除学名外,可以再取一个小名(或雅号),但并不能创造出另一个人来。(2)typedef与#define有相似之处,但二者是不同的:前者是由编译器在编译时处理的;后者是由编译预处理器在编译预处理时处理的,而且只能作简单的字符串替换。,8.7typedef的使用,本章小结,本章详细讨论了结构体的概念、定义和使用方法,通过实例介绍了结构体数组与指针,以及用结构体数据作为函数参数和返回值的使用方法,还详细介绍了链表的概念、定义、特点、操作方式等。另外,本章还介绍了能够在相同存储区域中存储不同数据类型的另一种构造类型公用体以及有关枚举类型和用户定义类型的概念和应用。,本章作业,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!