用户自定义数据类型.ppt

上传人:max****ui 文档编号:11546373 上传时间:2020-04-28 格式:PPT 页数:60 大小:643KB
返回 下载 相关 举报
用户自定义数据类型.ppt_第1页
第1页 / 共60页
用户自定义数据类型.ppt_第2页
第2页 / 共60页
用户自定义数据类型.ppt_第3页
第3页 / 共60页
点击查看更多>>
资源描述
第九章用户自定义数据类型,第九章用户自定义数据类型一、结构体的概念及使用二、结构体数组三、结构体指针四、链表的概念及基本操作五、共用体的概念及使用六、9.6枚举类型七、9.7用typedef定义类型,系统给定的数据类型,在基本类型基础上自己定义的,C语言的数据类型,考虑一个学生的基本信息包括:学号、姓名、性别、年龄、成绩、住址等。这对一名学生来说是一个整体,可以反映出学生的基本情况,如果用单个变量分别表示这几项,例如:sum:学号name10:姓名sex:性别age:年龄score:成绩addr30:住址不能体现出它们之间的内在联系。所以,希望有一种变量,来表示所有这些数据,也就是,把这些基本变量,作为一个整体构成一个新的变量,这种变量就是我们要介绍的结构体变量。,9.1结构体,结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-自定义数据类型结构体类型定义,struct结构体名类型标识符成员名;类型标识符成员名;.;,成员类型可以是基本型或构造型,struct是关键字,不能省略,合法标识符可省:无名结构体,分号不能省略,例structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;,结构体类型定义描述结构的组织形式,不分配内存,例如:要想把学生基本情况作为一个整体加以处理,比如:学号、姓名、性别、年龄、成绩、住址等。必须定义结构体类型,例structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;structstudentstu1,stu2;,1、先定义结构体类型,再定义结构体变量一般形式:,struct结构体名类型标识符成员名;类型标识符成员名;.;struct结构体名变量名表列;,定义结构体变量之后为其分配内存单元,结构体变量的定义,2、定义结构体类型的同时定义结构体变量一般形式:,struct结构体名类型标识符成员名;类型标识符成员名;.变量名表列;,例structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;,3、直接定义结构体变量一般形式:,struct类型标识符成员名;类型标识符成员名;.变量名表列;,例structintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;,用无名结构体直接定义变量只能一次,说明结构体类型与结构体变量概念不同类型:不分配内存;变量:分配内存结构体类型是一个模型,类似系统给定的基本类型比如int、float等类型,只是结构体类型是用户自定义的而已。结构体可嵌套结构体成员名与程序中变量名可相同,不会混淆,引用规则结构体变量不能整体引用,只能引用变量成员,成员(分量)运算符优先级:1结合性:从左向右,引用方式:结构体变量名.成员名,结构体变量的引用,可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用,结构体变量的引用,形式一:,例structstudentintnum;charname20;charsex;intage;charaddr30;structstudentstu1=112,“WangLin”,M,19,“200BeijingRoad”;,结构体变量的初始化,struct结构体名类型标识符成员名;类型标识符成员名;.;struct结构体名结构体变量=初始数据;,形式二:,例structstudentintnum;charname20;charsex;intage;charaddr30;stu1=112,“WangLin”,M,19,“200BeijingRoad”;,struct结构体名类型标识符成员名;类型标识符成员名;.结构体变量=初始数据;,形式三:,例structintnum;charname20;charsex;intage;charaddr30;stu1=112,“WangLin”,M,19,“200BeijingRoad”;,struct类型标识符成员名;类型标识符成员名;.结构体变量=初始数据;,结构体数组的定义三种形式:,形式一:structstudentintnum;charname20;charsex;intage;structstudentstu30;,形式二:structstudentintnum;charname20;charsex;intage;stu30;,形式三:structintnum;charname20;charsex;intage;stu30;,9.2结构体数组,例统计候选人选票,#includestructpersoncharname20;intcount;leader3=“Li”,0,“Zhang”,0,”Wang“,0;main()inti,j;charleader_name20;for(i=1;i=10;i+)scanf(%s,leader_name);for(j=0;jsex,p-age);,用指向结构体的指针作函数参数用结构体变量的成员作参数-值传递用指向结构体变量或数组的指针作参数-地址传递用结构体变量作参数-值传递,效率低,structstudentvoidf(structstudentstu2).stu1=.;.main().f(stu1);,structstudentvoidf(structstudent*p).stu1=.;.main().f(,structstudentvoidf(longnum)longnum;charname10;stu1=.;.main().f(stu1.num);,构造数据类型,也叫联合体用途:使几个不同类型的变量共占一段内存(相互覆盖)共用体类型定义定义形式:,union共用体名类型标识符成员名;类型标识符成员名;.;,例uniondatainti;charch;floatf;,类型定义不分配内存,9.5共用体,形式一:uniondatainti;charch;floatf;a,b;,形式二:uniondatainti;charch;floatf;uniondataa,b,c,*p,d3;,形式三:unioninti;charch;floatf;a,b,c;,共用体变量的定义,共用体变量定义分配内存,长度=最长成员所占字节数,共用体变量任何时刻只有一个成员存在,共用体变量引用引用方式:,引用规则不能引用共用体变量,只能引用其成员,共用体变量中起作用的成员是最后一次存放的成员,例unioninti;charch;floatf;a;a=1;(),在定义共用体变量时只能初始化第一个成员,例unioninti;charch;floatf;a=1,a,1.5;(),可以用一个共用体变量为另一个变量赋值,例floatx;unioninti;charch;floatf;a,b;a.i=1;a.ch=a;a.f=1.5;b=a;()x=a.f;(),例将一个整数按字节输出,运行结果:i=60501ch0=101,ch1=141ch0=A,ch1=a,main()unionint_charinti;charch2;x;x.i=24897;printf(i=%on,x.i);printf(ch0=%o,ch1=%onch0=%c,ch1=%cn,x.ch0,x.ch1,x.ch0,x.ch1);,结构体与共用体区别:存储方式不同,联系:两者可相互嵌套类比:结构体与共用体的定义形式类似,变量定义方式类似,成员引用方式类似。,例结构体中嵌套共用体,structintnum;charname10;charsex;charjob;unionintclass;charposition10;category;person2;,概念:对于数组,编译系统为其分配连续的一片存储单元,而链表,通过动态分配内存,实现链表中各元素(结点)的数据存放在非连续的单元中.,如:structstudentintnum;charname10;structstudent*next;/*next是指向该结构体类型的指针变量,;用来存放下一个结点的起始地址,实现将各结点连接成链*/,9.4链表,动态分配内存函数:格式1:viod*malloc(unsignedintsize)功能:在内存的动态存储区中分配长度为size(单位:byte)连续空间,返回该连续域的首地址(是无类型指针);未成功,返回0。,structstudentintnum;charname10;structstudent*next;*pt;pt=(structstudent*)malloc(sizeof(structstudent)ptnumname10next,格式2:calloc(n,size)功能:与malloc(size)相同,区别是分配n个长度为size的连续空间。可以为一为数组开辟动态存储空间。,格式:viodfree(viod*p)功能:释放由p指向的内存区,使这部分内存区能被其它变量使用。P是最近一次调用calloc或malloc函数时返回的值。free无返回值。例如:free(p);,numscorenext,建立动态链表例题:写一个函数建立一个有若干名学生数据的单向动态链表,当学号为0建表结束。设结点的结构体类型如下:structstudentlongnum;floatscore;structstudent*next;,numscorenext,实现此要求的算法如下:,head,p1,p2,null,9910189.5,head,p2,p1,9910378,n=1,9910378,9910378,head,p2,9910189.5,p1,n=2,建立链表的函数可以如下:#defineNULL0while(p1-num!=0)#defineLENsizeof(structstudent)n=n+1;structstudentif(n=1)head=p1;longnum;elsep2-next=p1;floatscore;p2=p1;structstudent*next;p1=(structstudent*)malloc(LEN);scanf(“%ld,%f”,可以在主函数中调用函数creat.例如:main()creat();输出链表例题:编写一个输出链表的函数printvoidprint(structstudent*head)在主函数中调用structstudent*p;方式printf(“nNow,These%drecordsare:n”,n);main()p=head;if(head!=NULL).doprint(head);printf(“%ld5.1fn”,p-num,p-score);p=p-next;while(p!=NULL);,A0,A0,A0,Alinkedlist,Deletionfromalinkedlist,Insertionintoalinkedlist,对链表的删除操作例题:写一函数以删除动态链表中指定的结点。函数del如下:structstudent*del(structstudent*head,longnum)structstudent*p1,*p2;if(head=NULL)printf(“nlistnull!n”);gotoend;p1=head;while(num!=p1-num,对链表的插入操作。设已有一个学生链表,各结点是按其成员项num(学号)的值由小到大顺序排序的。今要插入一个新生的结点,要求按学号的顺序插入。插入函数insert如下:structstudent*insert(structstudent*head,structstudent*stud)structstudent*p0,*p1,*p2;p1=head;p0=stud;if(head=NULL)head=p0;p0-next=NULL;elsewhile(p0-nump1-num),p0,准备插入的节点,p2,p1,对链表的综合操作将以上建立、输出、删除、插入的函数组织在一个程序中,用函数main作主调函数。可以写出main函数(main函数的位置在以上个函数的后面)main()structstudent*head,stu;longdel_num;printf(“inputrecords:n”);head=creat();print(head);printf(“ninputthedeletednumber:”);scanf(“%ld”,通用的主函数为:main()structstudent*head,*stu;longdel_num;printf(“inputrecords:n”);head=creat();print(head);printf(“ninputthedeletednumber:”);scanf(“%ld”,建立链表变量设置:head指向结构体类型指针变量,一般用它指向链表头。p1指向结构体类型指针变量,指向新的结点首地址。p2指向结构体类型指针变量,指向尾结点的首地址。,9909,:,:,9909,:,:,9910,:,:,9911,:,:,p1p2,p2,p1p2,p1,head,.,定义headp1,p2,n=0,动态分配,输入结点内数据,p2nextNULL,返回head,p1num!=0?,nn+1,动态分配,p2p1,headp1,p2nextp1,n=1?,输入结点内数据,N,Y,N,Y,p1,n=1n=2n=3,#defineLENsizeof(structstudent)structstudentintnum;floataver;structstudent*next;intn;structstudent*creat()/*该函数是建立链表的,它返回的指针,是指向该链表在内存存放首地址*/structstudent*head,*p1,*p2;n=0;p1=p2=(structstudent*)malloc(LEN);/*动态分配内存*/scanf(“%d,%f”,1,1.5,输出链表,phead,返回,输出数据,ppnext,head!=NULL?,p!=NULL?,N,Y,N,Y,pri(head)structstudent*head;structstudent*p;p=head;if(head!=NULL)doprintf(“%d%fn”,pnum,paver);p=pnext;while(p!=NULL);,删除链表中结点,.,.,.,headp2,p1,.,.,n=1,n=2n=3,删除某结点,不是将此结点真正从内存清除,而是将该节点在链表中的联系断开。如:要删除第二个结点,就把第一个结点最后的指针不是指第2结点首地址,而指第3个结点首地址。程序中要考虑以下几种情况:删除第一个结点:headheadnext;删除其它结点:(例删第二个结点)p2nextp1next;,框图:,head!=NULL?,未找到与未结束?,找到,p1=head?,p1head,p2p1,p1p1next,返回,p2nextp1next,返回,nn-1,headp1next,未找到,N删其它结点,删头结点,Y,N是空表,Y,N,structstudent*del(structstudent*head,intnum)structstudent*p1,*p2;if(head=NULL)printf(“listhull!n”);return(head);p1=head;while(num!=p1num,链表中插入结点操作(从小到大)在一个有序链表中,插入某结点后,也是有序表,是空表?,插入第一个结点?,找插入位置?,找到?,headp0,p0nextNULL,p2p1,p1p2next,p1nextp0p0nextNULL,nn+1,headp0,p2nextp0,p0nextp1,Y,N,Y,N,Y,N,N,Y,插到最后,非空表,空表插入第一个结点,p0指向要插入的结点,程序中要考虑以下几种情况:P0是要插入点,p1首先指向头结点。是空表:将该结点插入,作为头结点。非空表:插入位置是头结点:headp0,p0nextp1插入位置是非头,非尾结点(p2后,p1前):p2nextp0,p0nextp1插入位置是尾结点:p1nextp0,p0nextNULL,structstudent*insert(structstudent*head,structstudent*stud)structstudent*p0,*p1,*p2;p1=head;p0=stud;if(head=NULL)head=p0;p0next=NULL;/*是空表*/elsewhile(p0nump1num)/*插入链表最后*/,功能:用自定义名字为已有数据类型命名类型定义简单形式:typedeftypename;,例typedefintINTEGER;,类型定义语句关键字,已有数据类型名,用户定义的类型名,例typedeffloatREAL;,类型定义后,与已有类型一样使用,例INTEGERa,b,c;REALf1,f2;,说明:1.typedef没有创造新数据类型2.typedef是定义类型,不能定义变量3.typedef与define不同,definetypedef预编译时处理编译时处理简单字符置换为已有类型命名,9.6用typedef定义类型,typedef定义类型步骤按定义变量方法先写出定义体如inti;将变量名换成新类型名如intINTEGER;最前面加typedef如typedefintINTEGER;用新类型名定义变量如INTEGERi,j;,例定义数组类型inta100;intARRAY100;typedefintARRAY100;ARRAYa,b,c;,inta100,b100,c100;,例定义指针类型char*str;char*STRING;typedefchar*STRING;STRINGp,s10;,char*p;char*s10;,例定义函数指针类型int(*p)();int(*POWER)();typedefint(*POWER)();POWERp1,p2;,int(*p1)(),(*p2)();,例定义结构体类型structdateintmonth;intday;intyear;d;,例定义结构体类型structdateintmonth;intday;intyear;DATE;,例定义结构体类型typedefstructdateintmonth;intday;intyear;DATE;,例定义结构体类型DATEbirthday,*p;,structdateintmonth;intday;intyear;birthday,*p;,类型定义可嵌套,例typedefstructclubcharname20;intsize;intyear;GROUP;typedefGROUP*PG;PGpclub;,GROUP*pclub;structclub*pclub;,GROUP为结构体类型PG为指向GROUP的指针类型,若某个变量只存在有限的几种取值。可定义成枚举类型;例:enumweekdaysun,mon,twe,wed,thu,fri,set;enumcolorred,blue,while,black,yellow;定义枚举类型和变量的格式同结构体和共用体。枚举的成员按常量处理,不是变量(不能赋值),按顺序有固定的值(0,1-),也可改变其值。如:enumweekdayworkday;weekday=mon;printf(“%dn”,workday)/*输出1*/若:enumweekdaysun=7,mon=1,tue,wed,thu,fri,satworkday;workday=tue;printf(“%dn”,workday)/*输出2*/workday=2;/*整型数不能直接赋值给枚举变量,类型不匹配*/workday=(enumweekday)2;/*可以赋值,相当于将顺序号为2的枚举元素赋给workday*/,9.7枚举,例袋中有红、黄、白、蓝、黑五种颜色的球。每次从袋中取出3个球,问得到三种不同颜色的球的可能取法,输出每种组合的三种颜色。main()enumcolorred,yellow,blue,white,black;enumcolori,j,k,pri;intn=0,loop;for(i=red;i=black;i+)for(j=red;j=black;j+)if(i!=j)for(k=red;k=black;k+)if(k!=i),switch(pri)casered:printf(%-10s”,”red”);break;caseyellow:printf(%-10s”,”yellow”);break;caseblue:printf(%-10s”,”blue”);break;casewhite:printf(%-10s”,”white”);break;caseblack:printf(%-10s”,”black”);break;default:break;printf(“n”);printf(“ntotal:%5dn”,n);,运行结果:1redyellowblue2redyellowwhite3redyellowblack4redblueyellow5redbluewhite6redblueblack7:,已知staticinta=5,4,3,2,1;int*p=a+3,a+2,a+1,a,*q=p;则表达式*(p0+1)+*(q+2)的值是(),
展开阅读全文
相关资源
相关搜索

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


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

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


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