《用户自己建立数据类型ppt课件》由会员分享,可在线阅读,更多相关《用户自己建立数据类型ppt课件(151页珍藏版)》请在金锄头文库上搜索。
1、第第9章章 用用户户本人建立数据本人建立数据类类型型9.1定义和运用构造体变量定义和运用构造体变量9.2运用构造体数组运用构造体数组9.3构造体指针构造体指针9.4用指针处置链表用指针处置链表9.5共用体类型共用体类型9.6运用枚举类型运用枚举类型9.7用用typedef声明新类型名声明新类型名9.1 定定义义和运用构造体和运用构造体变变量量9.1.1本人建立构造体类型本人建立构造体类型9.1.2定义构造体类型变量定义构造体类型变量9.1.3构造体变量的初始化和援用构造体变量的初始化和援用9.1.1 本人建立构造体本人建立构造体类类型型用用户户本人建立由不同本人建立由不同类类型数据型数据组组成
2、的成的组组合型的数据构造,它称合型的数据构造,它称为为构造体构造体例如,一个学生的学号、姓名、性例如,一个学生的学号、姓名、性别别、年年龄龄、成果、家庭地址等、成果、家庭地址等项项,是属于同,是属于同一个学生的,因此一个学生的,因此组组成一个成一个组组合数据,合数据,如如student_1的的变变量,反映它量,反映它们们之之间间的的内在内在联络联络9.1.1 本人建立构造体本人建立构造体类类型型structStudentintnum;charname20;charsex;intage;floatscore;charaddr30;u由程序由程序设计者指定了者指定了一个构造体一个构造体类型型str
3、uct Studentu它包括它包括num,name,sex,age,score,addr等不同等不同类型的成型的成员9.1.1 本人建立构造体本人建立构造体类类型型声明一个构造体类型的普通方式为:声明一个构造体类型的普通方式为:struct构造体名构造体名成员表列成员表列;类型名类型名成员名成员名;9.1.1 本人建立构造体本人建立构造体类类型型阐明:阐明:(1)构造体类型并非只需一种,而是可以构造体类型并非只需一种,而是可以设计出许多种构造体类型,例如设计出许多种构造体类型,例如structTeacherstructWorkerstructDate等构造体类型等构造体类型各自包含不同的成员
4、各自包含不同的成员9.1.1 本人建立构造体本人建立构造体类类型型阐阐明:明:(2)成成员员可以属于另一个构造体可以属于另一个构造体类类型。型。structDateintmonth;intday;intyear;structStuintnum;charname20;charsex;intage;structDatebirthday;charaddr30;9.1.1 本人建立构造体本人建立构造体类类型型阐明:阐明:(2)成员可以属于另一个构造体类型。成员可以属于另一个构造体类型。numnamesexagebirthdayaddrmonthdayyear9.1.2 定定义义构造体构造体类类型型变变
5、量量前面只是建立了一个构造体前面只是建立了一个构造体类类型,它相当型,它相当于一个模型,并没有定于一个模型,并没有定义变义变量,其中并无量,其中并无详细详细数据,系数据,系统对统对之也不分配存之也不分配存储单储单元。元。相当于相当于设计设计好了好了图纸图纸,但并未建成,但并未建成详细详细的的房屋。房屋。为为了能在程序中运用构造体了能在程序中运用构造体类类型的型的数据,数据,该该当定当定义义构造体构造体类类型的型的变变量,并在量,并在其中存放其中存放详细详细的数据。的数据。9.1.2 定定义义构造体构造体类类型型变变量量1.先声明构造体类型,再定义该类型变量先声明构造体类型,再定义该类型变量声明
6、构造体类型声明构造体类型structStudent,可以,可以用它来定义变量用它来定义变量structStudentstudent1,student2;构造体类型名构造体类型名构造体变量名构造体变量名9.1.2 定定义义构造体构造体类类型型变变量量1.先声明构造体类型,再定义该类型变量先声明构造体类型,再定义该类型变量声明构造体类型声明构造体类型structStudent,可以,可以用它来定义变量用它来定义变量structStudentintnum;charname20;charsex;intage;floatscore;charaddr30;structStudentstudent1,stu
7、dent2;9.1.2 定定义义构造体构造体类类型型变变量量2.在声明在声明类类型的同型的同时时定定义变义变量量structStudentintnum;charname20;charsex;intage;floatscore;charaddr30;student1,student2;9.1.2 定定义义构造体构造体类类型型变变量量3.不指定类型名而直接定义构造体类型变量不指定类型名而直接定义构造体类型变量其普通方式为其普通方式为:struct成员表列成员表列变量名表列变量名表列;指定了一个无名的构造体类型指定了一个无名的构造体类型。9.1.2 定定义义构造体构造体类类型型变变量量structi
8、ntnum;charname20;charsex;intage;floatscore;charaddr30;student1,student2;9.1.2 定定义义构造体构造体类类型型变变量量阐明:阐明:(1)构造体类型与构造体变量是不同的概构造体类型与构造体变量是不同的概念,不要混同。只能对变量赋值、存取或念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,算。在编译时,对类型是不分配空间的,只对变量分配空间。只对变量分配空间。9.1.2 定定义义构造体构造体类类型型变变量量(2)构造体构造体类类型中
9、的成型中的成员员名可以与程序中的名可以与程序中的变变量名一量名一样样,但二者不代表同一,但二者不代表同一对对象。象。(3)对对构造体构造体变变量中的成量中的成员员 即即“域域 ,可,可以以单单独运用,它的作用与位置相当于普通独运用,它的作用与位置相当于普通变变量。量。例例9.1把一个学生的信息把一个学生的信息(包括学号、姓名、包括学号、姓名、性性别别、住址、住址)放在一个构造体放在一个构造体变变量中,然后量中,然后输输出出这这个学生的信息。个学生的信息。解解题题思思绪绪:本人建立一个构造体本人建立一个构造体类类型,包括有关学生信型,包括有关学生信息的各成息的各成员员用它定用它定义义构造体构造体
10、变变量,同量,同时赋时赋以初以初值值输输出出该该构造体构造体变变量的各成量的各成员员9.1.3 构造体构造体变变量的初始化和援用量的初始化和援用#includeintmain()structStudentlongintnum;charname20;charsex;charaddr20;a=10101,“LiLin,M,“123BeijingRoad;printf(NO.:%ldnname:%snsex:%cnaddress:%sn,a.num,a.name,a.sex,a.addr);return0;#includeintmain()structStudentlongintnum;charna
11、me20;charsex;charaddr20;a=10101,“LiLin,M,“123BeijingRoad;printf(NO.:%ldnname:%snsex:%cnaddress:%sn,a.num,a.name,a.sex,a.addr);return0;#includeintmain()structStudentlongintnum;charname20;charsex;charaddr20;a=10101,“LiLin,M,“123BeijingRoad;a.num=10010;对对printf(“%sn,a);不不对对#includeintmain()structStuden
12、tlongintnum;charname20;charsex;charaddr20;a=10101,“LiLin,M,“123BeijingRoad;b=a;对对structStudentb;b.num+;对对#includeintmain()structStudentlongintnum;charname20;charsex;charaddr20;a=10101,“LiLin,M,“123BeijingRoad;scanf(%ld,&a.num);对对scanf(“%ld,%s,%c,%sn,&a);错错#includeintmain()structDateintmonth;intday;i
13、ntyear;structStuintnum;charname20;charsex;intage;structDatebirthday;charaddr30;a,b;a.birthday.month=12;对对a.age=10;b.age=9;对对sum=a.age+b.age;对对例例9.2输输入两个学生的学号、姓名和成果,入两个学生的学号、姓名和成果,输输出成果出成果较较高学生的学号、姓名和成果高学生的学号、姓名和成果解解题题思思绪绪:(1)定定义义两个构造一两个构造一样样的构造体的构造体变变量量student1和和student2;(2)分分别输别输入两个学生的学号、姓名和成果;入两个学
14、生的学号、姓名和成果;(3)比比较较两个学生的成果,假两个学生的成果,假设设学生学生1的成果的成果高于学生高于学生2,就,就输输出学生出学生1的全部信息,假的全部信息,假设设学生学生2的成果高于学生的成果高于学生1,就,就输输出学生出学生2的全部信息。假的全部信息。假设设二者相等,二者相等,输输出出2个学生个学生的全部信息的全部信息#includeintmain()structStudentintnum;charname20;floatscore;student1,student2;scanf(%d%s%f,&student1.num,student1.name,&student1.score
15、);scanf(“%d%s%f,&student2.num,student2.name,&student2.score);不能加不能加&printf(Thehigherscoreis:n);if(student1.scorestudent2.score)printf(%d%s%6.2fn,student1.num,student1.name,student1.score);elseif(student1.scorestudent2.score)printf(%d%s%6.2fn,student2.num,student2.name,student2.score);elseprintf(%d%s
16、%6.2fn,student1.num,student1.name,student1.score);printf(%d%s%6.2fn,student2.num,student2.name,student2.score);return0;9.2 运用构造体数运用构造体数组组9.2.1定义构造体数组定义构造体数组9.2.2构造体数组的运用举例构造体数组的运用举例9.2.1定定义义构造体数构造体数组组例例9.3有有3个候选人,每个选民只能个候选人,每个选民只能投票选一人,要求编一个统计选票的投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后程序,先后输入被选人的名字,最后输出各人得票
17、结果。输出各人得票结果。9.2.1定定义义构造体数构造体数组组解解题题思思绪绪:设设一个构造体数一个构造体数组组,数,数组组中包含中包含3个元个元素素每个元素中的信息每个元素中的信息应应包括候包括候选选人的姓名人的姓名(字符型字符型)和得票数和得票数(整型整型)输输入被入被选选人的姓名,然后与数人的姓名,然后与数组组元素中元素中的的“姓名成姓名成员员比比较较,假,假设设一一样样,就,就给给这这个元素中的个元素中的“得票数成得票数成员员的的值值加加1输输出一切元素的信息出一切元素的信息#include#includestructPersoncharname20;intcount;leader3=
18、“Li,0,“Zhang,0,“Sun,0;全局的构造体数组全局的构造体数组name countleader0Li0Zhang0Sun0intmain()inti,j;charleader_name20;for(i=1;i=10;i+)scanf(“%s,leader_name);for(j=0;j3;j+)if(strcmp(leader_name,leaderj.name)=0)leaderj.count+;for(i=0;i3;i+)printf(%5s:%dn“,leaderi.name,leaderi.count);return0;leaderj.count=leaderj.coun
19、t+1;intmain()inti,j;charleader_name20;for(i=1;i=10;i+)scanf(“%s,leader_name);for(j=0;j3;j+)if(strcmp(leader_name,leaderj.name)=0)leaderj.count+;for(i=0;i3;i+)printf(%5s:%dn“,leaderi.name,leaderi.count);return0;阐阐明:明:(1)定定义义构造体数构造体数组组普通方式是普通方式是struct构造体名构造体名成成员员表列表列数数组组名名数数组长组长度度;先声明一个构造体先声明一个构造体类类型,
20、然后再用此型,然后再用此类类型定型定义义构造体数构造体数组组:构造体构造体类类型型数数组组名名数数组长组长度度;如:如:structPersonleader3;阐明:阐明:(2)对构造体数组初始化的方式是在定义数对构造体数组初始化的方式是在定义数组的后面加上:组的后面加上:初值表列初值表列;如:如:structPersonleader3=Li,0,Zhang,0,Fun,0;9.2.2 构造体数构造体数组组的运用的运用举举例例例例9.4有有n个学生的信息个学生的信息(包括学号、包括学号、姓名、成果姓名、成果),要求按照成果的高低,要求按照成果的高低顺顺序序输输出各学生的信息。出各学生的信息。解
21、解题题思思绪绪:用构造体数:用构造体数组组存放存放n个学生信个学生信息,采用息,采用选择选择法法对对各元素各元素进进展排序展排序(进进展比展比较较的是各元素中的成果的是各元素中的成果)。#includestructStudentintnum;charname20;floatscore;intmain()structStudentstu5=10101,Zhang,78,10103,Wang,98.5,10106,Li,86,10108,“Ling,73.5,10110,“Fun,100;structStudenttemp;constintn=5;inti,j,k;常变量常变量假设人数变为假设人数
22、变为3030#includestructStudentintnum;charname20;floatscore;intmain()structStudentstu5=10101,Zhang,78,10103,Wang,98.5,10106,Li,86,10108,“Ling,73.5,10110,“Fun,100;structStudenttemp;constintn=5;inti,j,k;#defineN5留意留意temp的类型的类型printf(Theorderis:n);for(i=0;in-1;i+)k=i;for(j=i+1;jstuk.score)k=j;temp=stuk;stu
23、k=stui;stui=temp;for(i=0;in;i+)printf(%6d%8s%6.2fn,stui.num,stui.name,stui.score);printf(n);return0;写法上与普通变量一致写法上与普通变量一致9.3 构造体指构造体指针针9.3.1指向构造体变量的指针指向构造体变量的指针9.3.2指向构造体数组的指针指向构造体数组的指针9.3.3用构造体变量和构造体变量的指用构造体变量和构造体变量的指针作函数参数针作函数参数9.3.1 指向构造体指向构造体变变量的指量的指针针指向构造体指向构造体对对象的指象的指针变针变量既可以指向量既可以指向构造体构造体变变量,也
24、可以用来指向构造体数量,也可以用来指向构造体数组组中的元素。中的元素。指指针变针变量的基量的基类类型必需与构造体型必需与构造体变变量的量的类类型一型一样样。例如:。例如:structStudent*pt;9.3.1 指向构造体指向构造体变变量的指量的指针针例例9.5经过经过指向构造体指向构造体变变量的指量的指针变针变量量输输出构造体出构造体变变量中成量中成员员的信息。的信息。解解题题思思绪绪:在已有的根底上,此:在已有的根底上,此题题要要处处理理两个两个问题问题:怎怎样对样对构造体构造体变变量成量成员赋值员赋值;怎怎样经过样经过指向构造体指向构造体变变量的指量的指针访问针访问构造构造体体变变量
25、中成量中成员员。#include#includeintmain()structStudentlongnum;charname20;charsex;floatscore;structStudentstu_1;structStudent*p;p=&stu_1;stu_1.num=10101;strcpy(stu_1.name,“LiLin);stu_1.sex=M;stu_1.score=89.5;printf(No.:%ldn,stu_1.num);printf(name:%sn,stu_1.name);printf(sex:%cn,stu_1.sex);printf(score:%5.1fn,
26、stu_1.score);return0;stu_110101LiLinM89.5pstructStudentstu_1;structStudent*p;p=&stu_1;stu_1.num=10101;strcpy(stu_1.name,“LiLin);stu_1.sex=M;stu_1.score=89.5;printf(No.:%ldn,stu_1.num);printf(name:%sn,stu_1.name);printf(sex:%cn,stu_1.sex);printf(score:%5.1fn,stu_1.score);return0;stu_110101LiLinM89.5p
27、(*p).num(*p).name(*p).sex(*p).score阐阐明:明:为为了运用方便和直了运用方便和直观观,C言言语语允允许许把把(*p).num用用p-num来替代来替代(*p).name等价于等价于p-name假假设设p指向一个构造体指向一个构造体变变量量stu,以下等价:,以下等价:stu.成成员员名名(如如stu.num)(*p).成成员员名名(如如(*p).num)p-成成员员名名(如如p-num)9.3.2 指向构造体数指向构造体数组组的指的指针针例例9.6有有3个学生的信息,放在构造体个学生的信息,放在构造体数组中,要求输出全部学生的信息。数组中,要求输出全部学生的信
28、息。解解题题思思绪绪:用指向构造体:用指向构造体变变量的指量的指针处针处置置(1)声明声明structStudent,并定,并定义义构造构造体数体数组组、初始化、初始化(2)定定义义指向指向structStudent类类型指型指针针p(3)使使p指向数指向数组组首元素,首元素,输输出元素中各出元素中各信息信息(4)使使p指向下一个元素,指向下一个元素,输输出元素中各出元素中各信息信息(5)再使再使p指向构造体数指向构造体数组组的下一个元素,的下一个元素,输输出它指向的元素中的有关信息出它指向的元素中的有关信息#includestructStudentintnum;charname20;char
29、sex;intage;structStudentstu3=10101,LiLin,M,18,10102,ZhangFun,M,19,10104,WangMin,F,20;intmain()structStudent*p;printf(No.Namesexagen);for(p=stu;pnum,p-name,p-sex,p-age);return0;10101Li LinM1810102Zhang FangM1910104Wang MinF20stu0stu1stu2intmain()structStudent*p;printf(No.Namesexagen);for(p=stu;pnum,p
30、-name,p-sex,p-age);return0;10101Li LinM1810102Zhang FangM1910104Wang MinF20pstu0stu1stu2intmain()structStudent*p;printf(No.Namesexagen);for(p=stu;pnum,p-name,p-sex,p-age);return0;10101Li LinM1810102Zhang FangM1910104Wang MinF20pstu0stu1stu2intmain()structStudent*p;printf(No.Namesexagen);for(p=stu;pn
31、um,p-name,p-sex,p-age);return0;10101Li LinM1810102Zhang FangM1910104Wang MinF20pstu0stu1stu29.3.3 用构造体用构造体变变量和构造体量和构造体变变量的指量的指针针作函数参数作函数参数将一个构造体变量的值传送给另一个函将一个构造体变量的值传送给另一个函数,有数,有3个方法。个方法。(1)用构造体用构造体变变量的成量的成员员作参数。作参数。例如,用例如,用stu1.num或或stu2.name作函数作函数实实参,将参,将实实参参值传给值传给形参。形参。用法和用普通用法和用普通变变量作量作实实参是一参是一样
32、样的,属于的,属于“值值传传送方式。送方式。该该当留意当留意实实参与形参的参与形参的类类型型坚坚持一致。持一致。(2)用构造体用构造体变变量作量作实实参。参。用构造体用构造体变变量作量作实实参参时时,将构造体,将构造体变变量所占量所占的内存的内存单单元的内容全部按元的内容全部按顺顺序序传传送送给给形参,形参,形参也必需是同形参也必需是同类类型的构造体型的构造体变变量量在函数在函数调调用期用期间间形参也要占用内存形参也要占用内存单单元。元。这这种种传传送方式在空送方式在空间间和和时间时间上开上开销较销较大大在被在被调调用函数期用函数期间间改改动动形参形参 也是构造体也是构造体变变量量 的的值值,
33、不能前往主,不能前往主调调函数函数普通普通较较少用少用这这种方法种方法(3)用指向构造体变量或数组元素的用指向构造体变量或数组元素的指针作实参,将构造体变量或数组元指针作实参,将构造体变量或数组元素的地址传给形参。素的地址传给形参。例例9.7有有n个构造体变量,内含学生学个构造体变量,内含学生学号、姓名和号、姓名和3门课程的成果。要求输出门课程的成果。要求输出平均成果最高的学生的信息平均成果最高的学生的信息(包括学号、包括学号、姓名、姓名、3门课程成果和平均成果门课程成果和平均成果)。解解题题思思绪绪:将:将n个学生的数据表示个学生的数据表示为为构造构造体数体数组组。按照功能函数化的思想,分。
34、按照功能函数化的思想,分别别用用3个函数来个函数来实现实现不同的功能:不同的功能:用用input函数函数输输入数据和求各学生平均成入数据和求各学生平均成果果用用max函数找平均成果最高的学生函数找平均成果最高的学生用用print函数函数输输出成果最高学生的信息出成果最高学生的信息在主函数中先后在主函数中先后调调用用这这3个函数,用指向个函数,用指向构造体构造体变变量的指量的指针针作作实实参。最后得到参。最后得到结结果。果。本程序假本程序假设设n=3#include#defineN3structStudentintnum;charname20;floatscore3;floataver;4个成员
35、个成员输入前输入前3个成员值个成员值计算最后成员值计算最后成员值intmain()voidinput(structStudentstu);structStudentmax(structStudentstu);voidprint(structStudentstu);structStudentstuN,*p=stu;input(p);print(max(p);return0;voidinput(structStudentstu)inti;printf(请输入各学生的信息:请输入各学生的信息:学号、姓名、三门课成果学号、姓名、三门课成果:n);for(i=0;iN;i+)scanf(%d%s%f%f
36、%f,&stui.num,stui.name,&stui.score0,&stui.score1,&stui.score2);stui.aver=(stui.score0+stui.score1+stui.score2)/3.0;输入第输入第1个成员值个成员值 输入第输入第2个成员值个成员值输入第输入第3个成员值个成员值计算第计算第4个成员值个成员值stu0stu1stu2stu10101Li78899888.33i=0voidinput(structStudentstu)inti;printf(请输入各学生的信息:请输入各学生的信息:学号、姓名、三门课成果学号、姓名、三门课成果:n);for
37、(i=0;iN;i+)scanf(%d%s%f%f%f,&stui.num,stui.name,&stui.score0,&stui.score1,&stui.score2);stui.aver=(stui.score0+stui.score1+stui.score2)/3.0;输入第输入第1个成员值个成员值 输入第输入第2个成员值个成员值输入第输入第3个成员值个成员值计算第计算第4个成员值个成员值stu0stu1stu2stu10101Li78899888.3310103Wang98.5876984.83i=1voidinput(structStudentstu)inti;printf(请输
38、入各学生的信息:请输入各学生的信息:学号、姓名、三门课成果学号、姓名、三门课成果:n);for(i=0;iN;i+)scanf(%d%s%f%f%f,&stui.num,stui.name,&stui.score0,&stui.score1,&stui.score2);stui.aver=(stui.score0+stui.score1+stui.score2)/3.0;输入第输入第1个成员值个成员值 输入第输入第2个成员值个成员值输入第输入第3个成员值个成员值计算第计算第4个成员值个成员值stu0stu1stu2stu10101Li78899888.3310103Wang98.5876984
39、.8310106Sun8876.58984.5i=2structStudentmax(structStudentstu)inti,m=0;for(i=0;istum.aver)m=i;returnstum;stu0stu1stu2stu10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5最大最大前往前往voidprint(structStudentstud)printf(n成果最高的学生是成果最高的学生是:n);printf(学号学号:%dn姓名姓名:%sn三三门课门课成果成果:%5.1f,%5.1f,%5.1fn平均成果平均
40、成果:%6.2fn,stud.num,stud.name,stud.score0,stud.score1,stud.score2,stud.aver);stud10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5numnamescoreaverstu0stu1stu2以上以上3个函数的个函数的调调用,情况各不一用,情况各不一样样:调调用用input函数函数时时,实实参是指参是指针变针变量,形量,形参是构造体数参是构造体数组组,传传送的是构造体元素的送的是构造体元素的地址,函数无前往地址,函数无前往值值。调调用用max函数函数时
41、时,实实参是指参是指针变针变量,形参量,形参是构造体数是构造体数组组,传传送的是构造体元素的地送的是构造体元素的地址,函数的前往址,函数的前往值值是构造体是构造体类类型数据。型数据。调调用用print函数函数时时,实实参是构造体参是构造体变变量,形量,形参是构造体参是构造体变变量,量,传传送的是构造体送的是构造体变变量中量中各成各成员员的的值值,函数无前往,函数无前往值值。9.4 用指用指针处针处置置链链表表9.4.1什么是链表什么是链表9.4.2建立简单的静态链表建立简单的静态链表9.4.3建立动态链表建立动态链表9.4.4输出链表输出链表9.4.1 什么是什么是链链表表链表是一种常见的重要
42、的数据构造链表是一种常见的重要的数据构造它是动态地进展存储分配的一种构造它是动态地进展存储分配的一种构造head12491249A661475B1475C10211021D0头指针头指针各结点地址不延续各结点地址不延续各结点含有两个部分各结点含有两个部分表尾表尾9.4.1 什么是什么是链链表表链链表是一种常表是一种常见见的重要的数据构造的重要的数据构造它是它是动态动态地地进进展存展存储储分配的一种构造分配的一种构造链链表必需利用指表必需利用指针变针变量才干量才干实现实现structStudentintnum;floatscore;structStudent*next;a,b,c;1010189
43、.510103901010785a结结点点b结结点点c结结点点a.next=&b;b.next=&c;numscorenext9.4.2 建立建立简单简单的静的静态链态链表表例例9.8建立一个如下图的简单链表,建立一个如下图的简单链表,它由它由3个学生数据的结点组成,要求输个学生数据的结点组成,要求输出各结点中的数据。出各结点中的数据。1010189.510103901010785a结点结点b结点结点c结点结点numscorenext9.4.2 建立建立简单简单的静的静态链态链表表解题思绪:解题思绪:1010189.510103901010785a结点结点b结点结点c结点结点numscoren
44、extheadhead=&a;a.next=&b;b.next=&c;NULLc.next=NULL;#includestructStudentintnum;floatscore;structStudent*next;intmain()structStudenta,b,c,*head,*p;a.num=10101;a.score=89.5;b.num=10103;b.score=90;c.num=10107;c.score=85;head=&a;a.next=&b;b.next=&c;c.next=NULL;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p
45、=p-next;while(p!=NULL);return0;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);return0;1010189.510103901010785a结点结点b结点结点c结点结点numscorenextheadNULLp相当于相当于p=&b;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);return0;1010189.510103901010785a结点结点b结点结点c结点结点numscorenexth
46、eadNULLp相当于相当于p=&b;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);return0;1010189.510103901010785a结点结点b结点结点c结点结点numscorenextheadNULLp相当于相当于p=&c;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);return0;1010189.510103901010785a结点结点b结点结点c结点结点numscorenextheadNULLp相当于相
47、当于p=&c;p=head;doprintf(“%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);return0;1010189.510103901010785a结点结点b结点结点c结点结点numscorenextheadNULLp相当于相当于p=NULL;静态链表静态链表9.4.3 建立建立动态链动态链表表所谓建立动态链表是指在程序执行过所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。据,并建立起前后相链的
48、关系。9.4.3 建立建立动态链动态链表表例例9.9写一函数建立一个有写一函数建立一个有3名学生数名学生数据的单向动态链表。据的单向动态链表。解解题题思思绪绪:定定义义3个指个指针变针变量:量:head,p1和和p2,它,它们们都是用来指向都是用来指向structStudent类类型数据型数据structStudent*head,*p1,*p2;解解题题思思绪绪:用用malloc函数开辟第一个函数开辟第一个结结点,并使点,并使p1和和p2指向它指向它p1p1=p2=(structStudent*)malloc(LEN);p2解解题题思思绪绪:读读入一个学生的数据入一个学生的数据给给p1所指的第
49、一个所指的第一个结结点点p1scanf(%ld,%f,&p1-num,&p1-score);p21010189.5解解题题思思绪绪:读读入一个学生的数据入一个学生的数据给给p1所指的第一个所指的第一个结结点点使使head也指向新开辟的也指向新开辟的结结点点headp1p2scanf(%ld,%f,&p1-num,&p1-score);1010189.5解解题题思思绪绪:再开辟另一个再开辟另一个结结点并使点并使p1指向它,接着指向它,接着输输入入该结该结点的数据点的数据headp1p21010189.5解题思绪:解题思绪:再开辟另一个结点并使再开辟另一个结点并使p1指向它,接着输指向它,接着输入
50、该结点的数据入该结点的数据headp1p21010189.5p1=(structStudent*)malloc(LEN);scanf(%ld,%f,&p1-num,&p1-score);1010390解解题题思思绪绪:使第一个使第一个结结点的点的next成成员员指向第二个指向第二个结结点,点,即即衔衔接第一个接第一个结结点与第二个点与第二个结结点点使使p2指向指向刚刚刚刚建立的建立的结结点点headp1p21010189.5p2-next=p1;1010390解题思绪:解题思绪:使第一个结点的使第一个结点的next成员指向第二个结点,成员指向第二个结点,即衔接第一个结点与第二个结点即衔接第一个
51、结点与第二个结点使使p2指向刚刚建立的结点指向刚刚建立的结点headp1p21010189.5p2-next=p1;1010390p2=p1;解解题题思思绪绪:再开辟另一个再开辟另一个结结点并使点并使p1指向它,接着指向它,接着输输入入该结该结点的数据点的数据headp1p21010189.51010390解题思绪:解题思绪:再开辟另一个结点并使再开辟另一个结点并使p1指向它,接着输指向它,接着输入该结点的数据入该结点的数据headp1p21010189.51010390p1=(structStudent*)malloc(LEN);scanf(%ld,%f,&p1-num,&p1-score)
52、;1010785解解题题思思绪绪:使第二个使第二个结结点的点的next成成员员指向第三个指向第三个结结点,点,即即衔衔接第二个接第二个结结点与第三个点与第三个结结点点使使p2指向指向刚刚刚刚建立的建立的结结点点headp1p21010189.510103901010785p2-next=p1;解题思绪:解题思绪:使第二个结点的使第二个结点的next成员指向第三个结点,成员指向第三个结点,即衔接第二个结点与第三个结点即衔接第二个结点与第三个结点使使p2指向刚刚建立的结点指向刚刚建立的结点headp1p21010189.510103901010785p2-next=p1;p2=p1;解解题题思思绪
53、绪:再开辟另一个再开辟另一个结结点并使点并使p1指向它,接着指向它,接着输输入入该结该结点的数据点的数据headp1p21010189.5101039010107850解题思绪:解题思绪:再开辟另一个结点并使再开辟另一个结点并使p1指向它,接着输指向它,接着输入该结点的数据入该结点的数据headp1p21010189.5101039010107850p1=(structStudent*)malloc(LEN);scanf(%ld,%f,&p1-num,&p1-score);解解题题思思绪绪:输输入的学号入的学号为为0,表示建立,表示建立链链表的表的过过程完成,程完成,该结该结点不点不应衔应衔接
54、到接到链链表中表中headp1p21010189.5101039010107850NULLp2-next=NULL;#include#include#defineLENsizeof(structStudent)structStudentlongnum;floatscore;structStudent*next;intn;structStudent类型数据的长度类型数据的长度structStudent*creat(void)structStudent*head,*p1,*p2;n=0;p1=p2=(structStudent*)malloc(LEN);scanf(“%ld,%f,&p1-num,
55、&p1-score);head=NULL;while(p1-num!=0)n=n+1;if(n=1)head=p1;elsep2-next=p1;p2=p1;p1=(structStudent*)malloc(LEN);scanf(“%ld,%f,&p1-num,&p1-score);p2-next=NULL;return(head);p1总总是开辟新是开辟新结结点点p2总总是指向最后是指向最后结结点点用用p2和和p1衔衔接两个接两个结结点点intmain()structStudent*pt;pt=creat();printf(“nnum:%ldnscore:%5.1fn,pt-num,pt-
56、score);return0;9.4.4 输输出出链链表表例例9.10编写一个输出链表的函数编写一个输出链表的函数print。100167.5100387100599NULLp解解题题思思绪绪:输输出出p所指的所指的结结点点使使p后移一个后移一个结结点点p100167.5100387100599NULLprintf(%ld%5.1fn,p-num,p-score);100167.5100387100599NULLp=p-next;解题思绪:解题思绪:输出输出p所指的结点所指的结点使使p后移一个结点后移一个结点printf(%ld%5.1fn,p-num,p-score);p100167.510
57、0387100599NULL解解题思思绪:输出出p所指的新所指的新结点点使使p后移一个后移一个结点点printf(%ld%5.1fn,p-num,p-score);p100167.5100387100599NULLp=p-next;解题思绪:解题思绪:输出输出p所指的新结点所指的新结点使使p后移一个结点后移一个结点printf(%ld%5.1fn,p-num,p-score);p100167.5100387100599NULLp=p-next;解解题思思绪:输出出p所指的新所指的新结点点使使p后移一个后移一个结点点printf(%ld%5.1fn,p-num,p-score);p相当于相当于p
58、=NULL;voidprint(structStudent*p)printf(nThese%drecordsare:n,n);if(p!=NULL)doprintf(%ld%5.1fn,p-num,p-score);p=p-next;while(p!=NULL);9.5 共用体共用体类类型型9.5.1什么是共用体类型什么是共用体类型9.5.2援用共用体变量的方式援用共用体变量的方式9.5.3共用体类型数据的特点共用体类型数据的特点9.5.1 什么是共用体什么是共用体类类型型有有时时想用同一段内存想用同一段内存单单元存放不同元存放不同类类型的型的变变量。量。使几个不同的使几个不同的变变量共享同一
59、段内存的量共享同一段内存的构造,称构造,称为为“共用体共用体类类型的构造。型的构造。1000100110021003字符字符ch整整 型型 变 量量 i实 型型 变 量量 f定定义义共用体共用体类类型型变变量的普通方式量的普通方式为为:union共用体名共用体名成成员员表列表列变变量表列;量表列;例如:例如:unionDatainti;charch;floatf;a,b,c;unionDatainti;charch;floatf;unionDataa,b,c;“共用体与共用体与“构造体的定构造体的定义义方式方式类类似,似,但它但它们们的含的含义义是不同的。是不同的。构造体构造体变变量所占内存量
60、所占内存长长度是各成度是各成员员占的内占的内存存长长度之和,每个成度之和,每个成员员分分别别占有其本人的占有其本人的内存内存单单元。而共用体元。而共用体变变量所占的内存量所占的内存长长度度等于最等于最长长的成的成员员的的长长度。度。9.5.2 援用共用体援用共用体变变量的方式量的方式只需先定义了共用体变量才干援用它,只需先定义了共用体变量才干援用它,但应留意,不能援用共用体变量,而只但应留意,不能援用共用体变量,而只能援用共用体变量中的成员。能援用共用体变量中的成员。例如,前面定义了例如,前面定义了a,b,c为共用体变量,为共用体变量,下面的援用方式是正确的:下面的援用方式是正确的:a.ia.
61、cha.f9.5.3 共用体共用体类类型数据的特点型数据的特点在运用共用体类型数据时要留意以下一在运用共用体类型数据时要留意以下一些特点:些特点:(1)同一个内存段可以用来存放几种不同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。其中一个成员,而不是同时存放几个。9.5.3 共用体共用体类类型数据的特点型数据的特点在运用共用体类型数据时要留意以下一在运用共用体类型数据时要留意以下一些特点:些特点:(2)可以对共用体变量初始化,但初始可以对共用体变量初始化,但初始化表中只能有一个常量。化表中只能有一个常量。9.5
62、.3 共用体共用体类类型数据的特点型数据的特点在运用共用体类型数据时要留意以下一在运用共用体类型数据时要留意以下一些特点:些特点:(3)共用体变量中起作用的成员是最后共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元的一个成员赋值后,原有变量存储单元中的值就取代。中的值就取代。9.5.3 共用体共用体类类型数据的特点型数据的特点在运用共用体在运用共用体类类型数据型数据时时要留意以下一要留意以下一些特点:些特点:(4)共用体共用体变变量的地址和它的各成量的地址和它的各成员员的的地址都是同一地址。地址都是同一地址。(
63、5)不能不能对对共用体共用体变变量名量名赋值赋值,也不能,也不能企企图图援用援用变变量名来得到一个量名来得到一个值值。9.5.3 共用体共用体类类型数据的特点型数据的特点在运用共用体类型数据时要留意以下一在运用共用体类型数据时要留意以下一些特点:些特点:(6)以前的以前的C规定不能把共用体变量作规定不能把共用体变量作为函数参数,但可以运用指向共用体变为函数参数,但可以运用指向共用体变量的指针作函数参数。量的指针作函数参数。C99允许用共用允许用共用体变量作为函数参数。体变量作为函数参数。9.5.3 共用体共用体类类型数据的特点型数据的特点在运用共用体类型数据时要留意以下一在运用共用体类型数据时
64、要留意以下一些特点:些特点:(7)共用体类型可以出如今构造体类型共用体类型可以出如今构造体类型定义中,也可以定义共用体数组。反之,定义中,也可以定义共用体数组。反之,构造体也可以出如今共用体类型定义中,构造体也可以出如今共用体类型定义中,数组也可以作为共用体的成员。数组也可以作为共用体的成员。9.5.3 共用体共用体类类型数据的特点型数据的特点例例9.11有假设干个人员的数据,其中有假设干个人员的数据,其中有学生和教师。学生的数据中包括:姓有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、数据包括:姓名、号码
65、、性别、职业、职务。要求用同一个表格来处置。职务。要求用同一个表格来处置。解题思绪:解题思绪:学生和教师的数据工程多数是一样的,但学生和教师的数据工程多数是一样的,但有一项不同。现要求把它们放在同一表格有一项不同。现要求把它们放在同一表格中中解题思绪:解题思绪:假设假设job项为项为s,那么第项为,那么第项为class。即。即Li是是501班的。假设班的。假设job项是项是t,那么第,那么第项为项为position。Wang是是prof教授教授。解题思绪:解题思绪:对第对第5项可以用共用体来处置将项可以用共用体来处置将class和和position放在同一段存储单元中放在同一段存储单元中#in
66、cludestructintnum;charname10;charsex;charjob;unionintclas;charposition10;category;person2;外部的构造体数组外部的构造体数组共用体变量共用体变量#includeunionCategintclas;charposition10;structintnum;charname10;charsex;charjob;unionCategcategoryperson2;声明共用体类型声明共用体类型定义共用体类型变量定义共用体类型变量intmain()inti;for(i=0;i2;i+)scanf(%d%s%c%c“,&
67、personi.num,&personi.name,&personi.sex,&personi.job);if(personi.job=s)scanf(%d“,&personi.category.clas);elseif(personi.job=t)scanf(“%s,personi.category.position);elseprintf(“Inputerror!);printf(n);for(i=0;isun)枚枚举举元素的比元素的比较规较规那么是按其在初始化那么是按其在初始化时时指定的整数来指定的整数来进进展比展比较较的。的。假假设设定定义时义时未人未人为为指定,那么按上面的默指定,那
68、么按上面的默许规许规那么那么处处置,即第一个枚置,即第一个枚举举元素的元素的值为值为,故,故monsun,satfri例例9.12口袋中有红、黄、蓝、白、黑口袋中有红、黄、蓝、白、黑5种种颜色的球假设干个。每次从口袋中先后取颜色的球假设干个。每次从口袋中先后取出出3个球,问得到个球,问得到3种不同颜色的球的能够种不同颜色的球的能够取法,输出每种陈列的情况。取法,输出每种陈列的情况。解题思绪:解题思绪:解题思绪:解题思绪:#includeintmain()enumColorred,yellow,blue,white,black;enumColori,j,k,pri;intn,loop;n=0;f
69、or(i=red;i=black;i+)for(j=red;j=black;j+)if(i!=j)for(k=red;k=black;k+)if(k!=i)&(k!=j)n=n+1;printf(“%-4d,n);for(loop=1;loop=3;loop+)switch(loop)case1:pri=i;break;case2:pri=j;break;case3:pri=k;break;default:break;switch(pri)casered:printf(“%-10s,“red);break;caseyellow:printf(%-10s,yellow);break;casebl
70、ue:printf(“%-10s,“blue);break;casewhite:printf(“%-10s,“white);break;caseblack:printf(%-10s,black);break;printf(n);printf(ntotal:%5dn,n);return0;9.7 用用typedef声明新声明新类类型名型名1.简单地用一个新的类型名替代原有的简单地用一个新的类型名替代原有的类型名类型名typedefintInteger;typedeffloatReal;inti,j;floata,b;与与Integeri,j;Reala,b;等价等价9.7 用用typedef声明
71、新声明新类类型名型名2.命名一个简单的类型名替代复杂的类型表命名一个简单的类型名替代复杂的类型表示方法示方法(1)命名一个新的类型名代表构造体类型:命名一个新的类型名代表构造体类型:typedefstructintmonth;intday;intyear;Date;Datebirthday;Date*p;9.7 用用typedef声明新声明新类类型名型名2.命名一个简单的类型名替代复杂的类型表命名一个简单的类型名替代复杂的类型表示方法示方法(2)命名一个新的类型名代表数组类型命名一个新的类型名代表数组类型typedefintNum100;Numa;9.7 用用typedef声明新声明新类类型名
72、型名2.命名一个简单的类型名替代复杂的类型表命名一个简单的类型名替代复杂的类型表示方法示方法(3)命名一个新的类型名代表一个指针类型命名一个新的类型名代表一个指针类型typedefchar*String;Stringp,s10;9.7 用用typedef声明新声明新类类型名型名2.命名一个简单的类型名替代复杂的类型表命名一个简单的类型名替代复杂的类型表示方法示方法(4)命名一个新的类型名代表指向函数的指命名一个新的类型名代表指向函数的指针类型针类型typedefint(*Pointer)();Pointerp1,p2;9.7 用用typedef声明新声明新类类型名型名归纳起来,声明一个新的起来
73、,声明一个新的类型名的方法是型名的方法是先按定先按定义变量的方法写出定量的方法写出定义体体inti;将将变量名量名换成新成新类型名将型名将i换成成Count在最前面加在最前面加typedeftypedefintCount用新用新类型名去定型名去定义变量量9.7 用用typedef声明新声明新类类型名型名以定以定义上述的数上述的数组类型型为例来例来阐明:明:先按定先按定义数数组变量方式量方式书写:写:inta100;将将变量名量名a换本本钱人命名的人命名的类型名:型名:intNum100;在前面加上在前面加上typedef,得到,得到typedefintNum100;用来定用来定义变量:量:Nu
74、ma;相当于定相当于定义了:了:inta100;9.7 用用typedef声明新声明新类类型名型名对字符指针类型,也是:对字符指针类型,也是:char*p;char*String;typedefchar*String;Stringp;9.7 用用typedef声明新声明新类类型名型名阐阐明:明:(1)以上的方法以上的方法实实践上是践上是为为特定的特定的类类型指定型指定了一个同了一个同义义字字(synonyms)。例如。例如typedefintNum100;Numa;Num是是int100的同的同义词义词typedefint(*Pointer)();Pointerp1;Pointer是是int(
75、*)()的同的同义词义词9.7 用用typedef声明新声明新类类型名型名阐阐明:明:(2)用用typedef只是只是对对曾曾经经存在的存在的类类型指型指定一个新的定一个新的类类型名,而没有型名,而没有发发明新的明新的类类型。型。(3)用用tyoedef声明数声明数组类组类型、指型、指针类针类型,型,构造体构造体类类型、共用体型、共用体类类型、枚型、枚举类举类型等,使型等,使得得编编程更加方便。程更加方便。(4)typedef与与#define外表上有外表上有类类似之似之处处9.7 用用typedef声明新声明新类类型名型名阐明:阐明:(5)当不同源文件中用到同一类型数据时,当不同源文件中用到
76、同一类型数据时,常用常用typedef声明一些数据类型。可以把声明一些数据类型。可以把一切的一切的typedef称号声明单独放在一个头称号声明单独放在一个头文件中,然后在需求用到它们的文件中用文件中,然后在需求用到它们的文件中用#include指令把它们包含到文件中。这样编指令把它们包含到文件中。这样编程者就不需求在各文件中本人定义程者就不需求在各文件中本人定义typefef称号了。称号了。9.7 用用typedef声明新声明新类类型名型名阐明:阐明:(6)运用运用typedef称号有利于程序的通称号有利于程序的通用与移植。有时程序会依赖于硬件特性,用与移植。有时程序会依赖于硬件特性,用用typedef类型就便于移植。类型就便于移植。