C语言程序设计教案第7章结构体与共用体第一讲内容说明主要内容重点难点问题提出说明1.结构体的概念及其基本操作2.结构体的引用方法3.结构体数组的使用例子:inta[5];通过举例说明定义结构体的必要性。和基本类型变量进行比较分析,进一步说明必须定义结构体类型。1.结构体的概念及基本操作2.结构体的引用方法结构体的概念及基本操作前面已经介绍了基本数据类型──整型、浮点型、字符型,也介绍了一种构造类型──数组,数组中各元素是属于同一种类型的。例如:一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项,各项的数据类型并不相同(如下图)numnamesexagescoreaddr10010LiFanm1888chengde如果将num、name、sex、age、score、addr分别定义为互相独立的简单变量,难以反映它们之间的内在联系,如何解决此类问题呢?一、结构体类型引入上例应该合数据组织成一个组合项,在一个组合项中包含若干个不同类型数据项,C语言没有提供这样的数据结构,因此用户必须在程序中建立所需结构体类型。Structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};Structstudent是一个类型名,Struct是一个关键字,标志着这是一个结构体类型。二、声明一个结构体的形式Struct结构体名{成员表列};其中,成员表列的格式为:类型名成员名;三、定义结构体类型变量的方法1.先声明结构体类型在定义变量名已定义了一个结构体类型Structstudent,可以用它定义变量。C语言程序设计教案内容说明比较说明举例举例Structstudent{intnum;┄charaddr[30];};Structstudentstudent1,student2;2.在声明类型的同时定义变量Structstudent{intnum;┄charaddr[30];}student1,student2;3.直接定义结构类型变量Struct{intnum;┄charaddr[30];}student1,student2;关于结构体类型的说明:(1)类型与变量不同;(2)成员可单独使用,作用和地位相当于普通变量;(3)成员可以是一个结构体变量;Structdate{intmonth;intday;intyear;}Structstudent{intnum;┄structdatebirthday;charaddr[30];}student1,student2;(4)成员名可以和程序中的变量名相同,二者不代表用一个对象。四、结构体变量的引用结构体变量名.成员名1.对结构体变量中的成员分别进行输入输出2.成员本身是结构体类型,只能对最低级的成员进行赋值等运算。3.对结构体成员的运算和普通变量一样进行各种运算。4.可以引用结构体变量的地址,也可引用结构体变量成员的地址。五、结构体变量的初始化和其它变量一样,对结构体变量可以在定义时指定初始值。例如{structstudent{longintnum;charname[20];只能对变量赋值、存取或运算,类型不行。先声明一个Structdate类型,然后在Structstudent类型时,将成员Birthday定义为Structdate类型。如:Student.numC语言程序设计教案内容说明引言举例Charsex;Charaddr[20];}a={89031,“lilin”,‘M’,“123beijingRoad”};六、结构体数组一个结构体变量中可以存放一组数据。如果有10个学生的数据需要参与运算,显然应该用数组,这就是结构体数组。1.结构体数组的定义Structstudent{intnum;┄charaddr[30];};Structstudentstudent[10];2.结构体数组的初始化其初始化和数组的初始化相似。3.结构体数组的应用举例例对候选人得票的统计程序。设有三个候选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果。程序如下:#includestdio.hstructperson{charname[20];intcount;}leader[3]={“li”,0,“zhang”,0,“fun”,0};main(){inti,j;charleader_name[20];for(i=1;i=10;i++){scanf(“%s”,leader_name);for(j=0;j3;j++)if(strcmp(leader_name,leader[j].name)==0)leader[j].count++;}for(i=0;i3;i++)printf(“%5s:%d\n”,leader[i].name,leader[i].count);}小结:理解和掌握结构体的概念和方法掌握结构体的基本操作熟练掌握结构体的引用方法了解结构体数组的使用结构体数组和数值型数组不同之处在于每个数组元素都是一个结构体类型的数据。定义了一个student,其元素为Structstudent类型数据,数组中有10个元素。C语言程序设计教案结构体与共用体第二讲内容说明主要内容重点难点举例结论说明引例1.指向结构体类型数据的指针2.用指针处理链表3.共用体通过举例说明定义结构体变量的指针。在主函数中声明了structstudent类型,然后定义structstudent类型的变量stu_1又定义了一个指针变量p它指向一个structstudent类型的数据。1.指向结构体类型数据的指针2.用指针处理链表指向结构体类型数据的指针;用指针处理链表一、如何使用指针变量指向结构体类型数据一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设个指针变量,用来指向一个结构体变量。例如:指向结构体变量的指针的应用#includestdio.hmain(){structstudent{longnum;charname[20];charsex;floatscore;};structstudentstu_1;structstudent*p;p=&stu_1;stu_1.num=89101;strcpy(stu_1.name,“lilin”);stu_1.sex=‘M’;stu_1.score=89.5printf(“No.%ld\nname:%s\nsex:%c\nscore:%f\n”,stu_1.num,stu_1.name,stu_1.sexstu_1.score);printf(“No.%ld\nname:%s\nsex:%c\nscore:%f\n”,(*p).num,(*p).name,(*p).sex(*p)1.score);};两个printf函数输出结果相同。以下三种形式等价:(1)结构体变量.成员名(2)(*p).成员名(3)p-成员名二、指向结构体数组的指针可以使用指针或指针变量指向数组或数组元素。对结构体数组及其元素也可以用指针或指针变量来指向。例指向结构体数组指针的应用structstudent{intnum;charname[20];charsex;intage;}C语言程序设计教案内容说明引言举例注释举例Structstudentstu[3]={{10101,“lilin”,‘M’,18},{10102,”zhangfun”,`M`,19}{10104,”wangmin”,`F`,20}};main(){Structstudent*p;printf(“No.namesexage\n”);for(p=stu;pstu+3;p++)printf(“%5d%-20s%2c%4d\n”,p-num,p-name,p-sex,p-age);}三、用指针处理链表链表是一种常见的数据结构,是动态地进行存储分配的一种结构。用数组存放数据时,必须事先定义固定的长度。比如有的班级有100人,有的班级有30人,如果要用同一个数组先后存放不同班级的学生数据,则必须定义长度为100的数组。如果事先难以确定一个班的最多人数,则必须把数组定的足够大,以便能存放任何班级的数据。显然这将会浪费内存。而链表是根据需要开辟存储单元。head1249135614751021链表有一个头指针变量,图中以head表示,它存放一个地址。该地址指向一个元素。链表中的每个元素称为“结点”,每个节点都应包括两部分:一为用户需要的实际数据,二为下一个结点的地址。链表中各元素在内存中不是连续存放的。要找某一个元素,必须找到上一个元素,根据它提供的下一个元素的地址才能找到下一个元素。这种链表的数据结构,必须利用指针变量才能实现。用结构体变量作为链表中的结点是最合适的。四、链表的建立和输出1.静态链表#defineNULL0{structstudent{longnum;floatscore;structstudent*next;};main(){structstudenta,b,c,*head,*p;a.num=99101;a.score=89.5;b.num=99103;b.score=90;c.num=99107;c.score=85;左侧是一个简单的链表结构head指向第一个元素,第一个元素又指向第二个元素……直到最后一个元素,该元素不在指向其它元素,它称为“表尾”。对结点num和score成员赋值。1249A1356B1475C1021DNullC语言程序设计教案内容说明思考举例举例head=&a;a.next=&b;b.next=&c;c.next=NULL;p=head;Do{printf(“%ld%5.1f\n”,p-num,p-score);p=p-next;}while(p!=NULL);}各个结点如何构成链表的?没有指针head行不行?p起到什么作用?没有它行不行?2.动态链表建立动态链表是指在程序执行过程中从无到有建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。例写一个函数建立一个有3名学生数据的单向动态链表#defineNULL0#defineLENsizeof(structstudent)structstudent{longnum;floatscore;structstudent*next;};intn;structstudent*creat(void){structstudent*head;structstudent*p1,*p2;n=0;p1=p2=(structstudent*)malloc(LEN);scanf(“%ld,%f”,&p1-num,&p1-score);head=NULLwhile(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);}3.输出链表将链表中的各结点的数据依次输出。例编写一个输出链表的函数printvoidprint(structstudent*head){printf(“\nNow,These%drecordare:\n”,n);p=head;if(head!=NULL)do将结点a,b,c的起始地址分别赋值。此链表属于静态链表。开辟一个新单元C语言程序设计教案内容说明图示举例举例{printf(“%ld%5.1f\n”,p-num,p-score);p=p-next;}while(p!=NULL);}五、对链表的删除操作已有一个链表,希望删除其中某个结点例写一个函数以删除动态链表中指定的结点。structstudent*del(structstudent*head,longnum){structstudent*p1,*p2;if(