1、第8章 结构、联合及枚举类型,*重点与难点 8.1 结构体类型和结构变量的定义 8.2 结构体变量的引用和初始化 8.3 结构体数组 8.4 结构体类型的指针变量,8.5 结构体与函数 8.6 用typedef定义类型 8.7 用指针处理链表 8.8 共用体 8.9 枚举类型 *本章小结 *作业,重点与难点,重点:结构体、共用体和枚举类型。 难点:链表的操作。,二维表(关系),8.1 结构体类型和结构体变量的定义,8.1.1 结构体类型的定义 8.1.2 结构体变量的定义,8.1.1 结构体类型的定义,struct 结构体名 数据类型 成员名1;数据类型 成员名2; 数据类型 成员名n; ;,
2、点坐标,二维坐标的点,struct point float x;float y; ;,点的结构体类型,圆的结构体,struct circle struct point float x;float y;dot;float r; ,struct point dot;,8.1.2 结构体变量的定义,1、先定义结构体类型,再定义结构体变量 2、定义结构体类型的同时定义结构体变量 3、直接定义结构体类型变量,1、先定义结构体类型,再定义结构体变量,struct circle struct point dot;float r; ; struct circle graph1,graph2;,2、定义结构体类
3、型的同时定义结构体变量,struct student int num;char name20;char sex;int agefloat score;char addr30; stu1,stu2;,3、直接定义结构体类型变量,struct int month;int day;int year; date1,date2;,8.2 结构体变量引用和初始化,1、结构体变量的引用 2、结构体变量的初始化,1、结构体变量的引用,在ANSI中除了允许具有相同类型的结构体变量相互赋值外,一般对结构体变量的引用是通过其成员来实现。 成员引用形式:,结构体变量名.成员名,举例:graph1.r graph1.d
4、ot.x,例8.1 求两个同心圆的面积差,main() struct point float x; float y; ;struct circle struct point dot; float r; ;struct circle graph1,graph2; float area;graph1.dot.x=2; graph1.dot.y=3; graph1.r=4;graph2.dot=graph1.dot; printf(“Graph2.r=“); scanf(“%f“, ,2、结构体变量的初始化,初始化形式结构体类型 结构体变量=初始化数据; 举例struct circle graph1
5、=2,3,4;即x=2,y=3,r=4; 其中内层可省。,8.3 结构体数组,struct circle cir3; struct credit int num;char *name;char sex;float score3 stu5;,结构体数组举例,struct credit int num;char *name;char sex;float score3;stu5=101,“Zhao Hua“,M,45,80,78,102,“Xian Jiang“,M,62.5,76,80,103,“Sun Jun“,F,92.5,92,89,104,“Li Wei“,F,87,88,91,105,“
6、Zhou Li“,M,58,60,77 ;,例8.2 计算学生的总分,按总分排名次及输出名次表,stui.total+=stui.scorej; 排序:选择法,for(i=0;istuk.total) k=j;if (k!=i) temp=stui;stui=stuk;stuk=temp;,8.4 结构体类型的指针变量,结构体变量可以由不同类型的成员构成,各个成员所占空间字节数之和是结构体变量所占的内存空间。 结构体的指针是结构体变量在内存中得首地址。 结构体类型的指针变量可以存放结构体的首地址。,成员引用方法,一般方法graph1.dot.x 指针方法已知p=(*p).r (*p).dot.
7、x或 p-r p-dot.x其中:“结构体指针变量名-成员名”方法直观。,举例:成员的指针引用方式,struct credit *p=,索引表结构,struct index int num;struct credit *link; index_id5,struct credit int num;char *name;char sex;float score3;float total;stu5;,索引图示,8.5 结构体与函数,结构体成员可以像简单变量一样作为函数的参数。 结构体变量也可以作为函数的参数。它的传递方式是值传递。由于在值传递时,实参拷贝到形参变量,如果结构体变量的成员较多、数据量较
8、大时,传递效率会很低。 一般采用结构体指针变量作为函数的参数。这样,在参数传递时仅需要拷贝一个地址而已。,例8.4 结构体与函数,void caltotal(struct credit stu,int n) int i,j;for(i=0;in;i+) stui.total=0;for (j=0;j3;j+) stui.total+=stui.scorej; ,形参也可以为:struct credit *p,int n,8.6 用typedef定义类型,typedef声明新的类型名来代替已有的类型名。 注意:typedef并不是创造新的类型。 举例:,typedef struct datein
9、t month;int day;int year; DATE;,DATE birthday;,声明一个新的类型名的步骤,1、先按定义变量的方法写出定义体int i; 2、将变量名换成新类型名将i换成COUNT 3、在最前面加typedeftypedef int COUNT 4、然后可以用新类型名去定义变量COUNT i,j;,举例,typedef int NUM100; NUM n;,typedef struct studentint num;char name20; STU; STU st1;,说明,typedef与define#define是在预编译时处理的,它只作简单的字符串替换;typ
10、edef是在编译时处理的,并不是作简单的字符串替换。 typedef的作用有利于程序的通用与移植。譬如:typedef int INTEGER;,课堂训练,1、 已知5个学生的数据存储在一个数组中,每个学生包括学号、姓名、3门课程的成绩和平均成绩。编写输入、输出函数: (1)输入函数:输入5个学生数据,计算平均分; (2)输出函数:在屏幕上输出5个学生的数据。,8.7 用指针处理链表,1、链表概述 2、简单链表 3、处理动态链表所需的函数 4、建立动态链表 5、输出链表 6、对链表的删除操作 7、对链表的插入操作 8、对链表的综合操作,1、链表概述,struct node char ch;st
11、ruct node *next; ; struct node *node1,*node2;,typedef struct node char ch;struct node *next; *NODE; NODE node1,node2;,2、简单链表(举例),#define NULL 0 struct student long num;float score;struct student *next; main() struct student a,b,c,*head,*p;a.num=99101;a.score=89.5;b.num=99103;b.score=90;c.num=99107;c
12、.score=85;head=,p=head;doprintf(“n%ld,%g“,p-num,p-score);p=p-next;while(p!=NULL);,3、处理动态链表所需的函数,4、建立动态链表,建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。,建立过程图示,head,创建链表函数,struct student *creat(void) struct student *head,*p1,*p2; int n=0;head=NULL; p2=head;while(1) p1=p2=(struct student
13、 *)malloc(sizeof(struct student);scanf(“%ld,%f“, ,head指向表头 p2指向表尾 p1指向新结点,5、输出链表,输出链表:首先要得到链表第一个结点的地址,即head的值,然后设一个指针变量p,先指向第一个结点,输出p所指的结点,然后使p后移一个结点,再输出,直到链表的尾结点。,编写一个输出链表的函数,void print(struct student *head) struct student *p;p=head;if(head!=NULL)do printf(“n%ld %5.1f“,p-num,p-score);p=p-next;while
14、(p!=NULL);else printf(“nlink table is empty!“); ,输出链表图示,head,6、对链表的删除操作,从动态链表中删除结点是将某个结点的前驱结点和它的后续结点链结起来。并将该结点所占的内存释放。,删除结点图示,head,删除结点程序,while(num!=p1-num ,7、对链表的插入操作,对链表的插入:是将一个结点插入到一个已有的链表中。,head,插入操作,if(head=NULL)head=p0;p0-next=NULL; else while(p0-nump1-num) ,链到表头,链到表尾,链到表中,8、对链表的综合操作,链表的综合操作包括
15、链表的建立、插入结点、删除结点和输出链表的结点数据等操作。其中,建立链表的操作可以由插入操作完成,插入操作可以控制链表的建立是有序的。,8.8 共用体,1、共用体的概念 2、共用体变量的引用方式 3、共用体类型数据的特点,1、共用体的概念,共用体:实现不同类型的变量存放在同一内存单元中,使用覆盖技术,几个变量相互覆盖。,共用体类型,定义一般形式,union 共用体名 成员表列 变量表列;,举例: union data int i;char ch;float f; a,b,c;,2、共用体变量的引用方式,引用方式:不能引用共用体变量,而只能共用变量中的成员。,举例: union data int
16、 i;char ch;float f; a,b,c;,成员引用: a.i a.ch a.f,共用体与结构体,例8.7 验证共用体变量的存储形式,main() union uarea char c_data; int i_data; float f_data; udata; printf(“ ,3、共用体类型数据的特点,1、每一瞬时只有一个成员起作用,其他的成员不起作用,即不是同时都存在和起作用。 2、新存入的成员值覆盖原来成员的值,只有最近一次存放的成员起作用。 3、共用体变量的地址与各个成员地址相同。 4、由于只有一个成员起作用,故不能使用定义共用体变量时对它初始化。同样地,不能把共用体作为
17、函数参数,也不能使函数返回值为共用体变量。,程序输出,程序运行情况: &udata is 65498 &udata.c_data is 65498, value is A &udata.i_data is 65498, value is 114 &udata.f_data is 65498, value is 1.18000e+02 &udata.i_data is 65498, value is 0,共用体应用举例,设有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、职务。根据职业(教师或学生)的不同,职务成员存放的值可以为职称(教师)或班级(学生)。从中可知,
18、“职务”成员应该是共用体,数据定义,struct int num;char name10;char sex;char job;unionint class;char position10;category; person2;,共用体变量,8.9 枚举类型,枚举:是指将变量的值一一列举出来,变量的值只限于列举出来值的范围内。 举例enum weekdaysun,mon,tue,wed,thu,fri,sat;其中:sun,mon.是枚举常量enum weekday workday,week_end;其中:workday,.是枚举变量,枚举常量,不能对它赋值; 枚举常量按定义时的顺序确定它们的值为
19、: 0,1,2,. 可以改变枚举元素的值: enum weekdaysun7,mon1,tue,wed,thu,fri,sat;,应用举例,口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中取出3个球,问得到3中不同色的球可能取法,打印出每种组合的3种颜色。分析:可以使用简单类型(1、2、.),使用枚举类型更直观。,枚举变量,枚举变量的值虽然整型值,但与整型量不同,需要进行强制转换: workday=(enum weekday)2;,例8.8 输入06,输出对应的星期英文名称,main() int x; enum days sun,mon,tue,wed,thu,fri,sat day
20、;printf(“Which day (06) is Today ?“); scanf(“%d“, ,程序,enum colorred,yellow,blue,white,black; enum color i,j,k,pri; switch(pri) case red: printf(“red“);break;case yellow:printf(“yellow“);break;default:break; ,课堂训练,2、 有一链表,编程实现各个结点数据的累加。已知每个结点是如下结构体:struct node float data;struct node *next;,本章小结(3点),结构体类型与结构体变量; 结构体变量的地址,成员的地址; 使用typedef定义类型名; 链表; 共用体; 枚举类型。,作业,p176 8.3, 8.5,