《结构、联合及枚举类型》由会员分享,可在线阅读,更多相关《结构、联合及枚举类型(65页珍藏版)》请在金锄头文库上搜索。
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 age float score; char addr30; stu1,stu2;,3、直接定义结构体类型变量,struct int month; int day; int year; date1,date2;,8.2 结构体变量引用和初始化,1、结构体变量的引用 2、结构体变量的初始化,1、结构体变量的引用,在ANSI中除了允许具有相同类型的结构体变量相互赋值外,一般对结构体变量的引用是通过其成员来实现。 成员引用形式:,结构体变量名.成员名,举例: gra
4、ph1.r graph1.dot.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、结构体变量的初始化,初始化形式 结构体类型 结构体变量=初始化数据; 举例
5、struct circle graph1=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,8
6、9, 104,“Li Wei“,F,87,88,91, 105,“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 结构体类型的指针变量,结构体变量可以由不同类型的成员构成,各个成员所占空间字节数之和是结构体变量所占的内存空间。 结构体的指针是结构体变量在内存中得首地址。 结构体类型的指针变量可以存放结构体的首地址。,成员引用方法,一般方法 g
7、raph1.dot.x 指针方法 已知p= (*p).r (*p).dot.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声明新的类型名来代替已有的类型名
9、。 注意:typedef并不是创造新的类型。 举例:,typedef struct date int month; int day; int year; DATE;,DATE birthday;,声明一个新的类型名的步骤,1、先按定义变量的方法写出定义体 int i; 2、将变量名换成新类型名 将i换成COUNT 3、在最前面加typedef typedef int COUNT 4、然后可以用新类型名去定义变量 COUNT i,j;,举例,typedef int NUM100; NUM n;,typedef struct student int num; char name20; STU; S
10、TU st1;,说明,typedef与define #define是在预编译时处理的,它只作简单的字符串替换;typedef是在编译时处理的,并不是作简单的字符串替换。 typedef的作用 有利于程序的通用与移植。譬如: typedef int INTEGER;,课堂训练,1、 已知5个学生的数据存储在一个数组中,每个学生包括学号、姓名、3门课程的成绩和平均成绩。编写输入、输出函数: (1)输入函数:输入5个学生数据,计算平均分; (2)输出函数:在屏幕上输出5个学生的数据。,8.7 用指针处理链表,1、链表概述 2、简单链表 3、处理动态链表所需的函数 4、建立动态链表 5、输出链表 6、
11、对链表的删除操作 7、对链表的插入操作 8、对链表的综合操作,1、链表概述,struct node char ch; struct 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,
12、*p; a.num=99101;a.score=89.5; b.num=99103;b.score=90; c.num=99107;c.score=85; head=,p=head; do printf(“n%ld,%g“,p-num,p-score); p=p-next; while(p!=NULL); ,3、处理动态链表所需的函数,4、建立动态链表,建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。,建立过程图示,head,创建链表函数,struct student *creat(void) struct student
13、 *head,*p1,*p2; int n=0; head=NULL; p2=head; while(1) p1=p2=(struct student *)malloc(sizeof(struct student); scanf(“%ld,%f“, ,head指向表头 p2指向表尾 p1指向新结点,5、输出链表,输出链表:首先要得到链表第一个结点的地址,即head的值,然后设一个指针变量p,先指向第一个结点,输出p所指的结点,然后使p后移一个结点,再输出,直到链表的尾结点。,编写一个输出链表的函数,void print(struct student *head) struct student
14、*p; p=head; if(head!=NULL) do printf(“n%ld %5.1f“,p-num,p-score); p=p-next; while(p!=NULL); else printf(“nlink table is empty!“); ,输出链表图示,head,6、对链表的删除操作,从动态链表中删除结点是将某个结点的前驱结点和它的后续结点链结起来。并将该结点所占的内存释放。,删除结点图示,head,删除结点程序,while(num!=p1-num ,7、对链表的插入操作,对链表的插入:是将一个结点插入到一个已有的链表中。,head,插入操作,if(head=NULL)h
15、ead=p0;p0-next=NULL; else while(p0-nump1-num) ,链到表头,链到表尾,链到表中,8、对链表的综合操作,链表的综合操作包括链表的建立、插入结点、删除结点和输出链表的结点数据等操作。其中,建立链表的操作可以由插入操作完成,插入操作可以控制链表的建立是有序的。,8.8 共用体,1、共用体的概念 2、共用体变量的引用方式 3、共用体类型数据的特点,1、共用体的概念,共用体:实现不同类型的变量存放在同一内存单元中,使用覆盖技术,几个变量相互覆盖。,共用体类型,定义一般形式,union 共用体名 成员表列 变量表列;,举例: union data int i; char ch; float f; a,b,c;,2、共用体变量的引用方式,引用方式:不能引用共用体变量,而只能共用变量中的成员。,举例: union data int 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、每