结构体与共用体zlh.ppt_第1页
结构体与共用体zlh.ppt_第2页
结构体与共用体zlh.ppt_第3页
结构体与共用体zlh.ppt_第4页
结构体与共用体zlh.ppt_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高级语言程序设计,计算机基础教研室,第8章结构体与共用体,C语言大学实用教程,南京邮电大学计算机学院计算机基础教研室,3,本章作业,作业本:P338页:8.68.7课堂练习或直接做在书上:P332337页:8.18.4,8.9,4,本章内容,结构体(结构structure)、共用体(联合union)类型的定义结构体变量、结构体数组向函数传递结构体变量、结构体数组用结构体实现动态数据结构链表的概念及操作原理选学内容,5,从基本数据类型到抽象数据类型,二进制数在早期的机器指令及汇编语言中,数据对象均用二进制数表示,有类型的概念,基本数据类型在高级语言中引入了基本数据类型:整型、实型、字符型等基本数据类型不能方便的解决所有问题,有些语言(如PL/1)中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法,用户自己构造数据类型-复合数据类型表示复杂的数据对象,典型的代表就是“结构体”,数组、指针也可算作此类,抽象数据类型(AbstractDataType,简称ADT)在复合数据类型基础上增加了对数据的操作类跨时代的进步,6,用户自定义的数据类型,结构体:把关系紧密且逻辑相关的多种不同类型的变量组织到统一的名字之下,也称复合数据类型这种类型的各成员变量占用相邻的一段内存单元共用体:把情形互斥但又逻辑相关的多种不同类型的变量组织在一起这种类型的各成员变量占用同一段内存单元,因此每一时刻只有一个成员数据起作用,7,8.1问题的提出,在程序里表示一个人(姓名、年龄、性别、),怎么表示?想表示多个人呢?如何用计算机程序实现下述表格的管理?,表8-1某学校学生成绩管理表,8,8.1问题的提出数组的解决方法,intstudentId30;/*最多可以管理30个学生,每个学生的学号用数组的下标表示*/charstudentName3010;charstudentSex302;inttimeOfEnter30;/*入学时间用int表示*/intscoreComputer30;/*计算机原理课的成绩*/intscoreEnglish30;/*英语课的成绩*/intscoreMath30;/*数学课的成绩*/intscoreMusic30;/*音乐课的成绩*/,9,8.1问题的提出数组的解决方法,intstudentId30=1,2,3,4,5,6;charstudentName3010=令狐冲,林平之,岳灵珊,任莹莹;charstudentSex302=男,男,女,女;inttimeOfEnter30=1999,1999,1999,1999;intscoreComputer30=90,78,89,78;intscoreEnglish30=83,92,72,95;intscoreMath30=72,88,98,87;intscoreMusic30=82,78,66,90;,10,8.1问题的提出数组的解决方法,数据的内存管理方式,分配内存不集中,寻址效率不高对数组进行赋初值时,容易发生错位结构显得比较零散,不容易管理,11,8.1问题的提出希望的内存分配图,12,structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;,形成一个样板,用于生成结构体变量。,一般形式:,struct结构体名类型关键字成员名1;类型关键字成员名2;.类型关键字成员名n;,构成结构体的变量称为结构体的成员(member),也称元素(element)或域(field),结构体的定义只定义了数据的形式,即声明了一种复杂的数据类型,并未生成任何变量。,8.2结构体类型与结构体变量,13,8.2结构体类型与结构体变量,前面学生管理的例子可以声明为以下结构体structSTUDENT/*定义一个类型*/intstudentID;/*每个学生的序号*/charstudentName10;/*每个学生的姓名*/charstudentSex4;/*每个学生的性别*/inttimeOfEnter;/*每个学生的入学时间*/intscoreComputer;/*每个学生的计算机原理成绩*/intscoreEnglish;/*每个学生的英语成绩*/intscoreMath;/*每个学生的数学成绩*/intscoreMusic;/*每个学生的音乐成绩*/;structSTUDENTstudents4;/*定义一个结构体数组*/,14,students0.studentIDstudents0.scoreComputer它们都是变量,一般称为结构的成员变量,15,8.2结构体类型与结构体变量typedef的用法,structstudentstudent1,student2;/*Itworks!*/studentstudent1,student2;/*Canthiswork?*/typedef为已经定义的数据类型定义一个“别名”格式:typedef原类型名新类型名,16,8.2结构体类型与结构体变量typedef的用法,structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;typedefstructstudentSTUD;STUDstudent1,student2;/*Itworks!*/,STUD与structstudent类型是同义词,17,先定义结构体类型再定义变量名,在定义类型的同时定义变量,structstudentstudent1,student2;,structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;student1,student2;,8.2结构体类型与结构体变量结构体变量的定义,18,8.2结构体类型与结构体变量结构体变量的定义,structintnum;charname20;charsex;intage;floatscore;charaddr30;student1,student2;,直接定义结构体变量(不出现结构体名),19,8.2结构体类型与结构体变量,double占用内存字节数=8structstudent占用内存字节数=?是所有成员变量的内存总和吗?事实上,所有数据类型在内存中都是从偶数地址开始存放的,且结构所占的实际空间一般是按照机器字长对齐的不同的编译器、平台,对齐方式会有变化我们可以用sizeof来获得结构的大小intsize;size=sizeof(structstudent);,20,定义:,structSTUDENTintstudentID;charstudentName10;charstudentSex4;structdatetimeOfEnter;intscoreComputer;intscoreEnglish;intscoreMath;intscoreMusic;,8.2结构体类型与结构体变量结构体的嵌套定义,structdateintyear;charmonth;charday;,结构体定义可以嵌套,21,8.2结构体类型与结构体变量指向结构体变量的指针,指向结构体的指针说明形式:struct结构名*结构指针名;例如:structSTUDENT*pt,stud1;ptpt-scoreMath=88;,25,8.2结构体类型与结构体变量结构体变量的引用和初始化,还可以用上述两种方法的结合(*指向结构体的指针变量名).成员名例如:(*pt).studentID=12;(*pt).scoreMath=88;,26,8.2结构体类型与结构体变量结构体变量的引用举例,structpointintx;inty;structpointpt;/*定义结构体变量*/structpoint*ppt;/*定义结构体指针*/ppt=,ppt,pt,怎样通过pt访问pt的成员?pt.x=0;/*成员运算符*/怎样通过ppt访问pt的成员?(*ppt).x=0;ppt-x=0;/*指向运算符*/第二种更常用,27,思考题,structpointintx;inty;structrectstructpointpt1;structpointpt2;,structrectrt;structrect*rp=下面表达式哪些合法?rt.pt1.x(*rp).pt1.xrp-pt1.xrt-pt1.x,上面合法的表达式都是等价的吗?,28,8.2结构体类型与结构体变量结构体变量的引用和初始化,结构体类型与其他数据类型一样,可在变量定义时初始化,因为结构体的成员类型千差万别,初始化时要注意数据类型的匹配.例如:structSTUDENTstud1=1,“令狐冲”,“男“,1999,12,20,90,83,78,92,29,8.3结构体数组结构体数组的定义,它定义了一个数组,最多可以包含30个元素,每个元素类型为structSTUDENT,structSTUDENTstu30;,按数组的定义,数组元素是连续存放的,每个元素又是一个结构体.,30,structSTUDENTstu30=1,令狐冲,男,1999,12,20,90,83,72,82,2,林平之,男,1999,07,06,78,92,88,78,3,岳灵珊,女,1999,07,06,89,72,98,66,4,任莹莹,女,1999,07,06,78,95,87,90;,8.3结构体数组结构体数组的初始化,31,8.3结构体数组结构体数组的指针,structSTUDENT*pt;pt=stu;,利用vc环境讲解例8.2,注意结构体数组的使用,32,8.4结构体与函数结构体与函数,向函数传递结构体的单个成员单向值传递,函数内对结构内容的修改不影响原结构向函数传递结构体的完整结构单向值传递,函数内对结构内容的修改不影响原结构,开销大向函数传递结构体的首地址用结构体数组或者结构体指针做函数参数除提高效率外,还可以修改结构体指针所指向的结构体的内容,33,8.4结构体与函数结构体与函数举例,有结构体类型定义如下structdateintyear;intmonth;intday;,voidfunc(structdatep)p.year=2006;p.month=12;p.day=25;,voidmain()structdated;d.year=1999;d.month=4;d.day=23;printf(“%d,%d,%dn”,d.year,d.month,d.day);func(d);printf(“%d,%d,%dn”,d.year,d.month,d.day);,1999,4,23,1999,4,23,单向值传递,voidfunc(structdate*p)p-year=2006;p-month=12;p-day=25;,main()structdated;d.year=1999;d.month=4;d.day=23;printf(“%d,%d,%dn”,d.year,d.month,d.day);func(,1999,4,23,2006,12,25,结构体指针做函数参数,36,例8.1:洗牌和发牌模拟(P306),一付扑克有52张牌,分为4种花色(Suit):黑桃(Spades)、红桃(Hearts)、草花(Clubs)、方块(Diamonds)每种花色有13张牌面(Face):A,2,3,4,5,6,7,8,9,10,Jack,Queen,King设计一个结构体表示一张牌,由两个成分组成:花色、牌面:structCARDcharsuit10;charface10;structCARDcard52;/*顺序存放扑克牌*/intresult52=70;/*存放洗发牌结果,初值可选为051以外的任意值*/char*suit=Spades,Hearts,Clubs,Diamonds;char*face=A,2,3,4,5,6,7,8,9,10,jack,Queen,King;,0123456789101112131415161718192021222324252627282930313233343536373839400000000000000111111111111122222222222223301234567891011120123456789101112012345678910111201,37,例8.1:洗牌和发牌模拟(P306),发牌过程将52张牌按照随机的顺序存放算法步骤:产生051的随机数,将其放于resulti内。i=i+1如果i=51,则重复第1步,否则,结束循环输出结果存在一个致命的问题:在重复第1步时,产生的随机数可能与以前产生的随机数相同,相同意味着52张牌中出现2张以上相同的牌,38,例8.1:洗牌和发牌模拟(P307),解决方法增加一步,判断新产生的随机数以前是否出现过如果出现过,则放弃;如果以前未出现过,则保留算法步骤:产生051的随机数m,将其放于resulti内。判断resulti在以前(result0resulti-1)是否出现过。如果出现过,则回到第1步;如果没出现过,则i=i+1如果i=51,则重复第12步,否则,结束循环输出结果,39,例8.1:洗牌和发牌模拟(P309),算法缺陷:随着生成随机数数量的增加,新的随机数与已经产生的随机数相同的可能性越来越大,有可能出现算法延迟问题高效算法先将52张牌按照花色与牌面顺序存放(cardi)再将其随机打乱每次循环,程序选择一个051的随机数j,然后将数组中当前的元素cardi与随机选出的元素cardj进行交换,40,例8.1改进:洗牌和发牌模拟(P313),用结构体数组做函数参数char*suit=Spades,Hearts,Clubs,Diamonds;char*face=A,2,3,4,5,6,7,8,9,10,jack,Queen,King;/*函数功能:将52张牌按黑桃、红桃、草花、方块花色顺序,面值按AK顺序排列函数参数:结构体数组wCard,表示不同花色和面值的52张牌指针数组wFace,指向面值字符串指针数组wSuit,指向花色字符串函数返回值:无*/voidFillCard(structCARDwCard,char*wFace,char*wSuit)inti;for(i=0;i52;i+)strcpy(wCardi.suit,wSuiti/13);strcpy(wCardi.face,wFacei%13);,i012345678910111213141516171819202122232425262728293031323334353637383940i/1300000000000001111111111111222222222222233i%1301234567891011120123456789101112012345678910111201,41,用结构体指针做函数参数/*函数功能:将52张牌的顺序打乱,函数参数:结构体数组wCard,表示52张牌函数返回值:无*/voidShuffle(structCARD*wCard)inti,j;structcardtemp;for(i=0;isecond=60)t-second=0;t-minute+;if(t-minute=60)t-minute=0;t-hour+;if(t-hour=24)t-hour=0;,voiddisplay(CLOCK*t)printf(%2d:%2d:%2dr,t-hour,t-minute,t-second);,实验十四结构体编程练习在屏幕上模拟显示一个数字式时钟,47,9.2返回指针的函数,数据类型*函数名(参数表)int*Te(intm,floatx)*号作为单目操作符比()的优先级低,只能说明函数的函数值是一个指向整型变量的指针,或者说函数返回一个地址变量,该地址变量是指向一个整型数据.例9.3,char*MyStrcat(char*s,char*t)char*p=s;while(*s!=0)s+;while(*t!=0)*s+=*t+;*s=0;returnp;,#include#defineARR_SIZE80main()charfirstARR_SIZE=“hello”;charsecondARR_SIZE=“world”;char*result=null;result=MyStrcat(first,second);printf(“nTheresultis:%sn”,result);,49,9.3函数指针,指向函数的指针变量的定义形式:数据类型(*指针名)();含义:定义一个指针变量用来存放函数的入口地址。Note1)指向是不固定的。2)不能使用*(p+1),例9.4求a,b,c三个数中的最大者,#includeintMax(intma,intmb,intmc);main()inta,b,c,max=0;int(*p)();printf(“pleaseinput3numbers(a,b,c):”);scanf(“%d,%d,%d”,intmax(intma,intmb,intmc)inttempMax;tempMax=mamb?ma:mb;tempMax=tempMaxmc?tempMax:mc;returntempMax;,51,8.5动态数据结构链表的定义,结构体声明时不能包含自我,但可以包含指向本结构体类型的指针变量链表(Linkedtable)structLinkintdata;structLink*next;,52,8.5动态数据结构,对链表的基本操作对链表的基本操作有:创建、检索(查找)、插入、删除和修改等。(1)创建:即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。(2)检索:按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,检索失败。(3)插入:在结点ki-1与ki之间插入一个新的结点k,使线性表的长度增1。(4)删除:删除结点ki,使线性表的长度减1。,53,8.5动态数据结构-动态链表的建立,准备工作#include#defineNULL0#defineLENsizeof(structnodetype)/*定义结点长度*/structLinkintdata;structLink*next;structLink*head;/*建立一个指向链表头的全局变量*/,structLink*CreateNode(intnodeNumbers)structLink*p;p=(structLink*)malloc(LEN);if(p=NULL)printf(“Noenoughmemorytoalloc”);exit(0);p-data=nodeNumbers*10;p-next=NULL;printf(“nCreateanewnode!”);returnp;,函数功能:建立一个新的节点,并为该节点赋初值,函数返回值:指向该节点的指针,55,动态链表的访问,voidDispLink(structLink*head)structLink*p;intj=1;p=head;doprintf(“n%d%dn”,j,p-data);p=p-next;j+;while(p!=NULL),函数功能:显示所有节点的节点号和数据项内容,main()inti=0;structLink*pr;charc;head=NULL;while(1)printf(“nPleasepressitoinsertonenewnode”);c=getch();if(c!=i,if(i=0)head=CreateNode(i);pr=head;elsepr-next=CreateNode(i);pr=pr-next;i+;DispLink(head);,演示过程:,NULL,head,0,30NULL,head,pr=p,Step1:找到需要删除的节点,保留该节点的上一个节点于pr中;Step2:取该节点指向下一个节点的指针p-next,将此指针赋给上一个节点的指针域中的pr-next;Step3:要删除的节点已经脱离了链表,删除完成,释放被删除的节点,链表的删除操作,59,8.5动态数据结构-链表的删除操作,structLink*Delnode(structLink*head,intnum)structLink*p,*pr;if(head=NULL)printf(“nNoLinkedTable”);return(head);p=head;while(num!=p-a,if(num=p-data)if(p=head)head=p-next;elsepr-next=p-next;free(p);printf(“deletethenode”);elseprintf(“nNotfoundtheNode”);returnhead;,插入结点,Step1:申请一段内存,建立一个新节点;Step2:找到要插入的位置,保存前一个节点指针到pr中;Step3:将新节点的指针域p-next指针指向原链表的后一个节点,p-next=pr-next;Step4:将前一个节点的指针域赋为新节点,pr-next=p;,pr,head,先下后上,structLink*insertNode(structLink*head,inttData)structLink*pr,*p;p=(structLink*)malloc(LEN);if(p=NULL)printf(“Cantenoughmemorytoalloc”);exit(0);pr=head;p-next=NULL;p-data=tData*10;if(head=NULL)head=p;elsewhile(pr-datadata,if(pr=head)p-next=head;head=p;returnhead;if(pr-next=NULL)pr-next=p;elsep-next=pr-next;pr-next=p;returnhead;,if(pr-next)p-next=pr-next;pr-next=p;,64,实验十五链表操作,建立一个单链表用于存储若干学生信息,包括:学号、姓名、某门课成绩,需要先定义节点数据类型noteType,65,8.6共用体,unionnumbershortx;charch;floaty;基本上和struct一样x、ch和y处于同样的地址sizeof(unionnumber)取决于占空间最多的那个成员变量,同一内存单元在每一瞬时只能存放其中一种类型的成员;起作用的成员是最后一次存放的成员不能作为函数参数,66,structpersoncharname20;c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论