第九章结构结构结构数组结构指针链表位运算自定义类型学号姓名性别出生地出生年出生月出生日数学物理程序设计学号姓名性别出生地年月日数学物理程序设计出生日期国家省市/县学习成绩结构:同一个数据项的若干成分构成的一个整体。例如:学生档案,每个学生有学号、姓名、性别、出生地、出生年月、学业成绩等。9.1结构9.1.1结构的定义structstudent{longintnum;charname[20];floatscore;};定义一个结构类型:structstudent9.1.2结构变量的定义1、先定义结构类型,再定义变量structstudent{longintnum;charname[20];floatscore;};structstudentstu1,stu2;numnamescorestu1200011Zhang85stu2200012Li942、定义结构类型的同时定义变量structstudent{longintnum;charname[20];floatscore;}stu1,stu2;3、不指定类型名,只定义变量struct{longintnum;charname[20];floatscore;}stu1,stu2;9.1.3结构变量的初始化只有全局变量或静态变量才能初始化。staticstructstudentstu2={200012,“Li”,94};numnamescorestu2200012Li94numnamescorestu1200011Zhang85structstudent{longnum;charname[20];floatscore;}stu1={200011,Zhang,85};9.1.4结构变量的使用1、结构类型变量的整体引用(1)不能整体输入输出,但相同类型的变量可以互相赋值printf(%ld%s%f,stu1);非法stu2=stu1;合法(2)可以引用结构体变量的地址printf(%x,&stu1);输出stu1的首地址2、结构变量中分量的引用structstudent{longintnum;charname[20];floatscore;}stu1,stu2;(1)结构变量.分量stu1.num=9901;printf(%s,stu2.name);numnamescorestu1200011Zhang85stu2200012Li94(2)结构变量中的分量可以依据它的类型进行各种运算x=stu1.score;strcpy(stu1.name,“Wang”);(3)可以引用结构变量中的分量的地址scanf(%ld,&stu1.num);9.2结构数组一个结构变量只能存放一个学生的资料。若班上有20个学生,需要用结构数组。即,数组中的每个元素都是结构类型。9.2.1定义structstudent{longintnum;charname[20];floatscore;}stu[20];stu[0]200011Zhang85stu[19]200012Li90200029Zhao70stu[1]9.2.2初始化structstudent{longintnum;charname[20];floatscore;}stu[20]={{200011,”Zhang”,85},{200012,”Li”,90}};stu[0]200011Zhang85stu[19]200012Li90200029Zhao70stu[1]9.2.3引用structstudent{longintnum;charname[20];floatscore;}stu[20];stu[0].numstu[0].namestu[0].scorestu[0]200011Zhang85stu[19]200012Li90200029Zhao70stu[1]程序举例例1、输入某班30位学生的姓名及数学、英语成绩,计算并输出每位学生的平均分。structstudent{charname[10];intmath,eng;floataver;};voidmain(){structstudents[30];inti;for(i=0;i30;i++){scanf(%s%d%d,s[i].name,&s[i].math,&s[i].eng);s[i].aver=(s[i].math+s[i].eng)/2.0printf(%s%f,s[i].name,s[i].aver);}}s[0]s[29]s[1]Zhang8085Li7790wang6078输入某班30位学生的姓名及数学、英语成绩,计算并输出每门课程的平均分。voidmain(){structstudents[30];inti;floataver_m=0,aver_e=0;例2for(i=0;i30;i++){scanf(%s%d%d,s[i].name,&s[i].math,&s[i].eng);aver_m+=s[i].math;aver_e+=s[i].eng;}printf(%f%f,aver_m/30,aver_e/30);}输入30位学生的姓名及数学、英语成绩,输出平均分最高的学生的姓名及其数学和英语成绩。structstudent{charname[10];intmath,eng;floataver;};例3voidmain(){structstudents[30];inti,sub;for(i=0;i30;i++){scanf(%s%d%d,s[i].name,&s[i].math,&s[i].eng);s[i].aver=(s[i].math+s[i].eng)/2.0}sub=0;for(i=1;i30;i++)if(s[i].avers[sub].aver)sub=k;printf(%s%d%d\n,s[sub].name,s[sub].math,s[sub].eng);}9.3结构指针9.3.1定义structstudent{longintnum;charname[20];floatscore;};structstudentstu1,*ptr;ptr=&stu1;numnamescorestu1200011Zhang85ptr9.3.2结构指针的使用structstudentstu1,*ptr=&stu1;stu1.num=200011;stu1.score=85;strcpy(stu1.name,”Zhang”);通过指针ptr访问结构分量(1)*ptr(*ptr).num=200011;(*ptr).score=85;strcpy((*ptr).name,”Zhang”);numnamescorestu1200011Zhang85ptr(2)-(*ptr).num=200011;ptr-num=200011;ptr-score=85;strcpy(ptr-name,”Zhang”);当ptr=&stu1时stu1.num(*ptr).numptr-num三者等价numnamescorestu1200011Zhang85ptrptr-num++等价于(ptr-num)++++ptr-num等价于++(ptr-num)(++ptr)-numnumnamescorestu1200011Zhang85ptr9.4链表9.4.1结构的嵌套定义structday{inty;intm;intd;}年月日成绩出生日期姓名学号structstudent{longintnum;charname[20];structdaybirthday;floatscore;}ymdscorebirthdaynamenumstructday{inty;intm;intd;};structstudent{longintnum;charname[20];structdaybirthday;floatscore;}stu1,stu2;ymdscorebirthdaynamenum或:structstudent{longintnum;charname[20];struct{inty,m,d;}birthday;floatscore;}stu1,stu2;structstudent{longintnum;charname[20];struct{inty,m,d;}birthday;floatscore;}stu1={9901,“Zhao”,{1980,10,30},80},stu2;stu2.birthday.y=1979;stu2.birthday.y=1;stu2.birthday.y=20;ymdscorebirthdaynamenum9.4.2单向链表structstudent{longintnum;floatscore;structstudent*next;}结构的递归定义head990180990290990375NULL1、动态内存分配函数(1)void*malloc(unsignedsize)功能:在内存的动态存贮区中分配一块长度为size的连续空间。返回值:指针,存放被分配内存的起始地址。若未申请到空间,则返回NULL(0)。void*:指向任何类型的数据,在使用时,要进行强制类型转换。例如:(int*)malloc(sizeof(int))(structstudent*)malloc(sizeof(structstudent))int*p1,*p2,a;P1=&a;*p1=345;P2=(int*)malloc(n*sizeof(int));*p2=123;p2++;*p2=456;p2++;*p2=999;(2)voidfree(void*ptr)功能:释放由malloc()申请的动态内存空间,ptr存放该空间的首地址。返回值:无。p=(structstudent*)malloc(sizeof(structstudent));……free(p);2、建立链表编写一个函数,要求用单向链表建立学生档案,从键盘输入数据,如果学号为0,输入结束,并返回链表的头指针。structstudent{longintnum;floatscore;structstudent*next;};structstudent*head,*tail,*p;head=tail=NULL;structstudent*head,*tail,*p;head=tail=NULL;size=sizeof(structstudent);p=(structstudent*)malloc(size);pnumscorenextheadtailptailhead=tail=NULL;inputnum,scorewhilenum!=0p=(structstudent*)malloc(sizeof(size))p-num=num,p-score=score,p-next=NULLyhead==NULLnhead=ptail-next=ptail=pinputnum,score#includestdio.hstructstudent{intnum;floatscore;structstudent*next;};structstudent*creat();main(){structstudent*head;head=creat();}structstudent*creat(){structstudent*head,*tail,*p;floatscore;intnum,size=sizeof(structstudent);head=tail=NULL;scanf(%d%f,&num,&score);while(num){p=(structstudent*)malloc(size);p-num=num;p-score=score;p-next=NULL;if(head==NULL)head=p;elsetail-next=p;tail=p;scanf(%d%f,&num,&score);}re