![[课件资料]第8章结构体与共用体_第1页](http://file.renrendoc.com/FileRoot1/2019-11/24/037ffb5a-5290-4cda-8534-3ae6922d008f/037ffb5a-5290-4cda-8534-3ae6922d008f1.gif)
![[课件资料]第8章结构体与共用体_第2页](http://file.renrendoc.com/FileRoot1/2019-11/24/037ffb5a-5290-4cda-8534-3ae6922d008f/037ffb5a-5290-4cda-8534-3ae6922d008f2.gif)
![[课件资料]第8章结构体与共用体_第3页](http://file.renrendoc.com/FileRoot1/2019-11/24/037ffb5a-5290-4cda-8534-3ae6922d008f/037ffb5a-5290-4cda-8534-3ae6922d008f3.gif)
![[课件资料]第8章结构体与共用体_第4页](http://file.renrendoc.com/FileRoot1/2019-11/24/037ffb5a-5290-4cda-8534-3ae6922d008f/037ffb5a-5290-4cda-8534-3ae6922d008f4.gif)
![[课件资料]第8章结构体与共用体_第5页](http://file.renrendoc.com/FileRoot1/2019-11/24/037ffb5a-5290-4cda-8534-3ae6922d008f/037ffb5a-5290-4cda-8534-3ae6922d008f5.gif)
已阅读5页,还剩95页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,第8章结构体与共用体,2,教学目标,理解结构体及结构体类型的定义掌握结构体成员的引用掌握结构体数组的声明和使用方法了解动态链式结构链表的基本操作掌握枚举类型了解共用体数据类型和基本的位运算,8.1问题引导,变量(很孤独)数组(挨着住,但必须类型一样)对于类型不同的相关联的数据还想挨着住,如何处理?,3,身份证的数据成分:姓名、性别、民族、出生日期、住址、身份证号码、照片等,4,C语言引入一种能集中不同数据类型于一体的构造类型结构体类型。结构体类型就是将不同数据类型的成员组合在一起,因此是不同数据类型成员的集合。,8.2结构体的声明和结构体变量定义,导引InforTable(人员信息)的属性学生ScoreTable(成绩表)的属性,5,8.2.1结构体的声明,用C语言提供的构造类型的型描述,6,成绩表:structScoreTablechargrade20;longnumber;charname20;floatkc1;floatkc2;,人员信息登记表:structInfoTablecharname20;charsex;charjob40;intage;longnumber;,结构体类型的定义形式:struct结构体名成员项表列;,7,8.2.2结构体变量的声明,结构体类型变量的定义的三种形式,8,先定义结构体数据类型,再定义变量structstudentcharname20;charsex;longnum;floatscore3;/*定义结构体类型变量*/structstudentstu1,stu2;,9,定义结构体类型同时定义变量structstudentcharname20;charsex;longnum;floatscore3;stu1,stu2;/*定义结构体类型变量*/,10,通过定义无名结构体数据类型定义变量structcharname20;charsex;longnum;floatscore3;stu1,stu2;/*定义该结构体类型变量*/,结构体变量stu1的结构如图:,11,printf(“%d”,sizeof(stu1);,结构体类型的嵌套定义(两种形式),12,structstudentcharname20;charsex;longnum;structdateintyear;intmoth;intday;birthday;,structdateintyear;intmoth;intday;structstudentcharname20;charsex;longnum;structdatebirthday;,8.2.3结构体成员的引用,成员访问:域访问运算符“.”,结构体变量是通过运算符访问结构体成员的。结构体类型变量名.成员名,13,structstudentstu1,stu2;stu1.sexstu1.numstu1.score0stu1.score1stu1.score2,结构体类型变量的定义和初始化为:structstudentcharname20;charsex;longnum;floatscore3;structstudentstu=“Wangyi”,f,1308001,98.5,97.0,95.0;,14,用括起,结构体类型变量完成初始化后,各成员的值分别为:,15,strcpy(,Wangyi“)stu.sex=fstu.num=1308001stu.score0=98.5stu.score1=97.0stu.score2=95.0,例8.1:结构体数据的输入与输出#includestructstudentcharname20;charsex;longnum;floatscore3;intmain()structstudentstu;inti;,16,scanf(“%s%c%ld”,,17,输入:WangyiM1308001L98.59795输出:*NameSexNumScore1Score2Score3WangyiM130800198.5097.0095.00,8.2.4结构体变量的赋值,两个类型相同的结构体变量可以用赋值符号进行相互赋值。structstudentstu1,stu2=“Wangyi”,f,1308001,98.5,97.0,95.0;stu1=stu2是合法的,相当于把stu2的成员值赋给stu1对应的成员两个类型相同的结构体变量不能进行算术运算、关系运算和逻辑运算。stu1=stu2,stu1stu2等都是不合法的,18,8.1.4结构体变量的赋值,一个结构体变量在使用时,如果没有使用成员运算符,那么是指整个结构体变量。通过赋值语句:sut1=stu2;注意:除赋值操作和本质是由赋值完成的操作外,不能通过整体去使用结构体变量,19,仅对赋值有效,如:stu1=stu2;或者,stu1stu2;,如:stu1=stu2;或者,stu1stu2;/*非法*/,8.3结构体数组和结构体指针,结构体数组的定义和元素的引用结构体类型数组的定义形式:struct结构体类型名数组名数组长度;,20,structstudentcharname20;longnum;floatscore3;structstudentstu30;/*定义了班级同学的信息*/,8.3.2结构体数组元素的赋值及引用,同前面数组一样,结构体数组元素也是通过下标来引用各元素,并通过成员引用符“.”来引用各自得成员,21,,stu0.num,stu0.scorei;,stu1.num,stu1.scorei;.,stu29.num,stu29.scorei;,例8.2:设一个班级有30个人,填写如下的登记表,除姓名、学号外,还有三科成绩,编程实现对表格的计算,求出班级学生的单科平均分,求解出每个人的三科总成绩,并按总成绩由高分到低分输出。,22,分析:将问题分解为己基本的输入、处理和输出三个基本的过程:输入:定义数据类型基本信息,实现均分计算处理:按学生的总成绩排序。输出:按表格要求输出。装配:定义main()函数,调用各子程序。,23,24,#include#defineN30voidinputdata();/*输入学生信息*/voidsortdata();/*对学生总分排序*/voidoutputdata();/*输出学生信息*/voidoutputaverage();/*输出课程平均分*/structstudent/*定义结构体*/charname20;/*学生姓名*/longnum;/*学号*/floatscore3;/*三科考试成绩*/floatsum;/*总成绩*/;structstudentstuN;/*定义了一个班级同学的信息*/,25,intmain()inputdata();sortdata();outputdata();outputaverage();return0;,26,voidinputdata()inti,j;for(i=0;iN;i+)scanf(%s%ld%f%f%f,,27,voidsortdata()inti,j;studenttemp;for(i=0;iN-1;i+)for(j=0;jN-1-i;j+)if(stuj.sumstuj+1.sum)temp=stuj;/*使用结构体变量的赋值操作*/stuj=stuj+1;stuj+1=temp;,28,voidoutputdata()inti;printf(*n);printf(NameNumScore1Score2Score3Sumn);for(i=0;in;i+)printf(%10s%8ld%8.2f%8.2f%8.2f%8.2fn,,stui.num,stui.score0,stui.score1,stui.score2,stui.sum);,29,voidoutputaverage()inti,j;floataver3=0;printf(*n);for(i=0;i3;i+)for(j=0;jnamep1-nump1-score0p1-score1p1-score2,32,例8.3对指向结构体类型变量的正确使用。输入一个结构体类型变量的成员,通过指向结构体变量的指针输出,33,#includestructstudentcharname20;charsex;longnum;floatscore3;intmain()structstudent*p;inti;,34,p=(structstudent*)malloc(sizeof(structstudent);scanf(%s%c%ld,p-name,指针变量访问结构体变量的成员的两种形式(*结构体指针变量名).成员名(*p).name(*p).sex(*p).num结构体指针变量名-成员名p-namep-sexp-num,35,8.3.4结构体数组和指针的应用,例8.4:用指针访问结构体变量及结构体数组,36,#includestructstudentintnum;charname20;charsex;intage;floatscore;intmain()structstudentstu3=11302,Wang,F,20,483,11303,Liu,M,19,503,11304,Song,M,19,471.5;structstudentstudent1=11301,Zhang,F,19,496.5,*p,*q;,8.2.4结构体数组和指针的应用,37,inti;p=,运行程序结果:输出:Zhang,F,86.0Wang,F,98.0Liu,M,90.0Song,M,95.0,8.4结构体与函数,在C语言中允许用结构变量作函数参数进行传递,将结构体成员逐个复制到形参中。函数的返回值也可以是结构体类型的。当成员为数组时将会使传送的时间和空间开销很大,严重地降低了程序的效率。使用指针,即用指针变量作函数参数,可减少时间和空间的开销。,38,8.4.1结构体变量作为函数参数,例8.5:定义一个复数类型的结构体,通过函数调用,求两个复数的和。,39,voidadd(structcomplex_tc1,structcomplex_tc2)structcomplex_tc;c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;c.modular=sqrt(c.real*c.real+c.imag*c.imag);printf(%lf,%lf,%lfn,c.real,c.imag,c.modular);,40,#include#includestructcomplex_tdoublereal;doubleimag;doublemodular;voidadd(structcomplex_t,structcomplex_t);intmain()structcomplex_tc1,c2;scanf(%lf%lf,结构体数组作为函数参数补充例题:学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,其功能是:把分数最低的学生数据放在h所指的数组中。注意:分数最低的学生可能不止一个,函数返回分数最低的学生的人数。,41,例8.6重新编写例8.2中的SortData函数,通过结构体数组作为参数的形式实现排序操作,42,voidSortData(student*pstu,intn)inti,j;studenttemp;for(i=0;in-1;i+)for(j=i;jnum=1308001;pnode1-sex=M;pnode1-next=NULL;/*NULL:表示为空的指针*/pnode2=(Node*)malloc(sizeof(Node);strcpy(pnode2-name,”Jerry”);pnode2-num=1308002;pnode2-sex=F;pnode2-next=NULL;/*NULL:表示为空的指针*/,执行pnode3=pnode2;,53,下列的表达式都为真pnode1!=pnode2pnode1!=pnode3pnode2=pnode3,54,定义:若存在一组结点类型的数据,在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为NULL或者0。这样一种连接方式称为“链表”,55,有三个结点指针分别是p1,p2,p3指向三个不同的结点数据执行下列代码:p1-next=p2;p2-next=p3;p3-next=NULL;,56,8.5.2链表的建立,链表的创建过程有以下几步:定义链表的数据结构。定义头节点指针,置指针域为空,表示创建了一个空表。申请一个节点存储单元。将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新节点接到表尾。判断一下是否有后续节点要接入链表,若有转到(3),否则结束。,57,8.4.2链表的建立,例8.8创建一个学生学号及姓名的链表,即结点包括学生学号、姓名及指向下一个结点的指针。,58,#include#includestructNodecharname20;longnum;structNode*next;structNode*create(structNode*);,59,structNode*create(structNode*head)structNode*newnode;structNode*q;newnode=(structNode*)malloc(sizeof(structNode);scanf(%s%ld,newnode-name,60,intmain()structNode*head=NULL,*p;head=create(head);if(head=NULL)printf(CreateListErrorn);exit(0);p=head;while(p-next)/*不输出最后一个学号name,p-num);p=p-next;return0;,链表的输出,链表的输出过程有以下几步找到表头。若是非空表,输出结点的成员,是空表则退出。移到下一个结点。转到(2)。,61,62,voidListshow(structnode*head)structnode*p;p=head;while(p)printf(%s,%ldn,p-name,p-num);p=p-next;,按学号排序,voidListSort(structnode*head)node*p,*s,*pt;p=head;pt=s=p-next;while(p-next!=NULL)while(s-next!=NULL)if(p-next-nums-next-num)pt-next=p-next;p-next=s-next-next;s-next=pt-next;s=s-next;p=p-next;pt=s;,63,8.5.3链表的插入,在链表中插入一个新的结点,64,例8.9:在例8.8创建的链表中插入一个结点,若学生已存在,输出其信息,否则插入链表中,65,List*insert_node(List*head,Node*node)List*p=head;List*prep=p;if(head=NULL|node=NULL)returnhead;while(p-next!=NULL)if(p-numnum)prep=p;p=p-next;,用于元素的定位,不断移动结点指针找到合适的插入点,elseif(p-num=node-num)printf(%salreadyexist!n,node-name);returnhead;elsebreak;if(head=p)/*若插入点在链表的头部,需改动head指针*/node-next=p;head=node;elsenode-next=prep-next;prep-next=node;returnhead;,66,8.5.4链表的删除,链表结点的删除定位删除点先将指针接在合适的位置上,在断开需要删除的结点释放删除点的存储单元,67,链表结点的删除,第一步:p1的指针域指向p3第二步:断开结点p2,68,p1-next=p3;free(p2);,structNode*delete_node(structNode*head,longnum)structNode*p=head,*prep=p;if(head=NULL)returnhead;while(p!=NULL)if(p-num!=num)prep=p;p=p-next;elsebreak;/*找到*/,69,70,if(head=p)/*删除点恰在head指针处,须修改head指针*/head=p-next;elseif(p-next!=NULL)prep-next=p-next;elseprep-next=NULL;/*删除点在最后一结点,直接将前一个结点的next域置空*/if(p=NULL)printf(“Notexist!n”);elsefree(p);returnhead;,8.6共用体,共用体(联合体),也是一种构造数据类型。一个共用体是几个类型不同(也可以相同)的成员的组合,其中每个成员各有一个名字在一个结构体(变量)里,结构体的各成员顺序排列存储,每个成员都有自己独立的存储位置。一个共用体变量的所有成员共享同一片存储区。一个共用体变量在每个时刻里只能保存某一个成员的值,71,8.6.1共用体的定义,共用体类型定义形式:union共用体名成员表列;,72,uniondatainta;floatb;doublec;chard;obj;,共用体数据类型与结构体在形式上非常相似,但其表示的含义及存储是完全不同的。,例8.11:结构体和共用体的存储空间对比uniondata/*共用体*/inta;floatb;doublec;chard;structstud/*结构体*/inta;floatb;doublec;chard;,73,intmain()printf(%d,%d,sizeof(structstud),sizeof(uniondata);return0;,程序运行结果:输出:17,8,74,8.6.2共用体变量的引用,例8.12:共用体变量的使用。#includeuniondatainta;floatb;doublec;chard;uniondatauntest;,75,intmain()untest.a=6;printf(“%dn”,untest.a);untest.c=67.2;printf(“%5.1lfn”,untest.c);untest.d=W;untest.b=34.2;printf(“%5.1lf,%cn”,untest.b,untest.d);printf(“n”);return0;,输出:667.234.2,?,先前写入的字符被覆盖了,所以字符的输出是无法得知的,由写入内存的数据决定。,8.7枚举型和自定义类型,枚举类型的定义和枚举变量的说明枚举:一系列命名的整型常量。特点:枚举类型的变量的取值是可数的是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。,76,8.7.1枚举类型的定义和枚举变量的说明,枚举的定义:enum枚举名枚举值表;enumWeekdaysun,mon,tue,wed,thu,fri,sat,77,该枚举名为Weekday,枚举值共有7个,即一周中的七天。凡被说明为Weekday类型变量的取值只能是七天中的某一天。,几种声明形式,先声明类型,再定义变量enumWeekdaysun,mon,tue,wed,thu,fri,sat;enumWeekdaya,b,c;声明类型的同时定义变量enumWeekdaysun,mon,tue,wed,thu,fri,sata,b,c;声明无名枚举类型变量enumsun,mon,tue,wed,thu,fri,sata,b,c;,78,8.7.2枚举类型变量的赋值和使用,枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。sun=5;sun=mon;都是错误的。枚举元素:由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2。在weekday中,sun值为0,mon值为1,sat值为6。,79,例8.13:枚举变量的赋值与引用#include#includeenumweekdaysun,mon,tue,wed,thu,fri,sata,b,c;intmain()a=sun;b=mon;c=tue;printf(%d,%d,%d,a,b,c);return0;,80,说明:只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。若a,b均为枚举变量,有:a=sum;b=mon;/*正确*/a=0;b=1;/*错误*/用强制类型转换a=(enumweekday)2;/*等价于a=tue;*/,81,枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号定义枚举类型数据时,指定了其初始的数值enumTesta,b=2,c,d;a的值为0,b的值指定为2,c,d的值?C语言规定:当指定了初始数值时,其后的枚举值为该数值之后的整数。即:c的值是3,d的值是4,82,8.7类型定义符typedef,允许用户为数据类型取“别名”,类型定义符typedef即可用来完成此功能格式为:typedef原类型名新类型名inta,b;int的完整写法为INTEGER,为了增加程序的可读性,将int重定义为:typedefintINTEGER,83,typedefcharNAME20;NAMEa1,a2,s1,s2;等价于:chara120,a220,s120,s220;,84,typedefstructstucharname20;intage;charsex;STU;STUbody1,body2;,可用宏定义来代替typedef的功能,但是宏定义是由预处理完成的,而typedef则是在编译时完成的,后者更为灵活方便,8.8位段*,有些信息在存储时,并不需要占用一个完整的字节。例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言提供了一种数据类型,称为“位域”或“位段”“位段”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。,85,8.8.1位域的定义和位域变量的说明,位域定义与结构体定义相仿,其形式为:struct位域结构体名类型说明符位域名:位域长度;,86,如:structbitsecinta:6;intb:2;intc:8;,8.8.1位域的定义和位域变量的说明,位域变量的说明与结构体变量说明的方式相同。可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:structbitsecinta:6;intb:2;intc:8;data;,87,说明data为bitsec变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。,说明:一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。举例structbitsecunsigneda:4;unsigned:0;/*空域,不使用的部分*/unsignedb:4;/*从下一单元开始存放*/unsignedc:4;,88,在这个位域定义中,a占第一数的4位,后4位填0表示不使用,b从第二数开始,占用4位,c占用第三个数的4位。,8.8.2位域的使用,位域的使用和结构体成员的使用相同,其一般形式为:位域变量名.位域名位域允许用各种格式输出。,89,8.8.2位域的使用,例8.14:位域的格式化输出#includestructbsunsigneda:1;unsignedb:3;unsignedc:4;bit,*pbit;intmain()bit.a=1;bit.b=7;bit.c=15;printf(%d,%d,%dn,bit.a,bit.b,bit.c);pbit=,90,pbit-a=0;pbit-b,8.9结构体的综合应用,例8.15:学生成绩信息包括学号、姓名、考试课程、平时成绩、期中成绩、期末成绩、总评成绩和等级(优:90-100、良:80-89、中:70-79、及格:60-69、不及格:60)。建立一个描述学生某科成绩的数据类型,其中总评成绩=平时成绩20%+期中成绩20%+期末成绩60%。要求输入学生的平时成绩、期中成绩、期末成绩。分别用函数实现下面功能:计算课程总评成绩并指出成绩等级。输出不及格的学生信息。按学生的总评成绩进行降序排列。,91,结构体声明,92,#include#include#defineN30typedefstructstudentintid;/*学生学号*/charname20;/*学生姓名*/charsubject20;/*考试科目*/floatperf;/*平时成绩*/floatmid;/*期中成绩*/floatfinal;/*期末成绩*/f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年房地产市场区域分化对长租公寓投资策略的影响分析
- 2025年老年健康管理中老年慢性病管理长期照护服务模式社区服务满意度调查报告
- 2025年文化旅游演艺项目策划运营中的互动体验设计研究报告
- 现场产品知识培训总结报告课件
- 2025年教师资格证考试(小学)教育案例分析专项训练试卷
- 2025年小学数学毕业升学考试易错题型专项复习押题试卷
- 现代化家具知识培训内容课件
- 2025年Python二级考试模拟试卷 高频考点实战版
- 林州一中分校2026届化学高一第一学期期中考试试题含解析
- 2026届浙江省湖州市9+1高中联盟长兴中学化学高三第一学期期末质量跟踪监视试题含解析
- 孩子抵抗力提升的方法与技巧
- 教学副校长给教师培训课件
- 一级建造师之一建矿业工程实务高分复习资料
- 交通信号设施施工技术交底
- 关于股权性质与货币市场的思考
- 市场监管个人纪律作风整顿心得体会
- 育婴员理论模拟考试试题及答案
- 小学数学教师业务水平考试试题
- 安全文明施工措施费支付申请表实用文档
- 杨式85式太极拳现用图解
- YY/T 1095-2015肌电生物反馈仪
评论
0/150
提交评论