《【教学课件】第9章结构体和共用体.ppt》由会员分享,可在线阅读,更多相关《【教学课件】第9章结构体和共用体.ppt(40页珍藏版)》请在三一办公上搜索。
1、第九章 结构体与共用体,9.1 结构体结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-自定义数据类型结构体类型定义,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;,成员类型可以是基本型或构造型,struct是关键字,不能省略,合法标识符可省:无名结构体,例 struct student int num;char name20;char sex;int age;float score;char addr30;,例 struct student int num;char name20;char sex;int age;float score;char addr3
2、0;struct student stu1,stu2;,结构体变量的定义先定义结构体类型,再定义结构体变量一般形式:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 变量名表列;,例#define STUDENT struct student STUDENT int num;char name20;char sex;int age;float score;char addr30;STUDENT stu1,stu2;,定义结构体类型的同时定义结构体变量一般形式:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.变量名表列;,例 str
3、uct student int num;char name20;char sex;int age;float score;char addr30;stu1,stu2;,直接定义结构体变量一般形式:,struct 类型标识符 成员名;类型标识符 成员名;.变量名表列;,例 struct int num;char name20;char sex;int age;float score;char addr30;stu1,stu2;,用无名结构体直接定义变量只能一次,说明结构体类型与结构体变量概念不同类型:不分配内存;变量:分配内存类型:不能赋值、存取、运算;变量:可以结构体可嵌套结构体成员名与程序中
4、变量名可相同,不会混淆结构体类型及变量的作用域与生存期,结构体变量的引用引用规则 结构体变量不能整体引用,只能引用变量成员,可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用,成员(分量)运算符优先级:1结合性:从左向右,引用方式:结构体变量名.成员名,结构体变量的初始化形式一:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 结构体变量=初始数据;,例 struct student int num;char name20;char sex;int age;char addr30;struct student stu1=112,Wang
5、Lin,M,19,200 Beijing Road;,形式二:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.结构体变量=初始数据;,例 struct student int num;char name20;char sex;int age;char addr30;stu1=112,Wang Lin,M,19,200 Beijing Road;,形式三:,struct 类型标识符 成员名;类型标识符 成员名;.结构体变量=初始数据;,例 struct int num;char name20;char sex;int age;char addr30;stu1=112,Wang
6、 Lin,M,19,200 Beijing Road;,9.3 结构体数组结构体数组的定义三种形式:,形式一:struct student int num;char name20;char sex;int age;struct student stu2;,形式二:struct student int num;char name20;char sex;int age;stu2;,形式三:struct int num;char name20;char sex;int age;stu2;,结构体数组初始化,例 struct int num;char name20;char sex;int age;s
7、tu=,;,顺序初始化:struct student int num;char name20;char sex;int age;struct student stu=100,Wang Lin,M,20,101,Li Gang,M,19,110,Liu Yan,F,19;,例 struct student int num;char name20;char sex;int age;stu=,;,结构体数组引用,引用方式:结构体数组名下标.成员名,例1:计算学生的平均成绩和不及格人数,struct student int num;char name20;float score;student15=1
8、001,Li ping,55,1002,Zhang ping,80,1003,Wang fang,75,1004,Cheng lin,82,1005,Wu yong,94;main()int i,c=0;float average,s=0;for(i=0;i5;i+),s+=student1i.score;if(student1i60)c+=1;average=s/5;printf(average=%fncount=%dn,average,c);,例2:建立同学通讯录,#include stdio.h#define NUM 3struct mem char name20;char phone1
9、0;main()struct mem manNUM;int i;for(i=0;iNUM;i+)printf(input name:);gets(mani.name);,printf(input phone:);gets(mani.phone);printf(namettphonenn);for(i=0;iNUM;i+)printf(%stt%sn,mani.name,mani.phone);,9.4 结构体和指针指向结构体变量的指针定义形式:struct 结构体名*结构体指针名;例 struct student*p;,使用结构体指针变量引用成员形式,存放结构体变量在内存的起始地址,指向运算符
10、优先级:1结合方向:从左向右,例 指向结构体的指针变量,例3:指向结构体变量的指针的应用struct student int num;char name20;float score;student1=1001,Zhang,75.5,*spoint;main()spoint=,指向结构体数组的指针,例3:指向结构体数组的指针,struct student int num;char name20;char sex;int age;stu3=10101,Li Lin,M,18,10102,Zhang Fun,M,19,10104,Wang Min,F,20;main()struct student*
11、p;for(p=stu;pnum,p-name,p-sex,p-age);,9.5.1 动态存储分配和链表的概念,动态存储分配:,由程序员控制的存储分配方法,根据需要临时分配内存单元以存放有用数据,当不用时,又可以释放存储单元,以便其用于分配给其它数据使用。,链表:,链表是动态进行存储分配的一种结构。若干数据(每个数据组称为一个结点)按一定的原则连接起来。,9.5 链表,1249,A,1356,B,1475,C,1021,D,NULL,head,1249,1356,1475,1021,简单的链表:,设置一指针变量,存放第一个结点的地址,称为头指针,一般以head命名。最后一个结点的地址项不指向
12、任何结点,赋以值NULL。,链表中每一个元素称为一个结点,结点是一组数据,包括用户需要的实际数据和下一个结点的地址。,前一个结点指向下一个结点,只有通过前一个结点才能找到下一个结点。,用c语言实现链表结构:包含指针项的结构体就是一个结点。,定义结点:struct studentint num;float score;struct student*next;,3010,99101,89.5,3028,head,3010,99103,90,4016,3028,99107,85,4016,NULL,A,B,C,num,score,next,例 建立一个简单链表,定义结点:struct student
13、long num;float score;struct student*next;a,b,c,*head;,赋予有用数据:a.num=99101;a.score=89.5;b.num=99103;b.score=90;c.num=99107;c.score=85;,建立链表:head=,9.5.2 用于动态链表的函数,C标准函数库中动态存储分配的函数:malloc()calloc(),malloc函数作用:,在内存中开辟指定大小的存储空间,并将此存储空间的起始地址作为函数返回值.,malloc函数的使用:,malloc(8)开辟长度为8个字节的存储空间,若其起始地址为1268,则malloc(
14、8)的返回值为1268,且返回的指针值指向void型.将此地址赋给一个指向long型的指针变量:p=(long*)malloc(8);开辟一个结点:malloc(sizeof(struct student);,calloc函数:,分配num个大小为size字节的空间,函数返回值为该空间的起始地址.,函数的作用:,函数的使用:,calloc(10,20)开辟10个大小为20字节的空间,函数返回该空间的起始地址.,链表应用,链表的特点:,链表每一个结点内必须包括一个指针项,指向下一结点.,链表所占内存区大小不固定,各结点在内存中的次序可以是任意的.,必须用malloc和calloc函数动态开辟单元
15、,且开辟的结点只能用指针方法访问.,若断开链表中某一个结点,其后的所有结点虽在内存中存在,但无法访问.,单向链表最后一个结点的指针项必须是NULL.,单向链表的访问只能从头指针开始,顺序进行.,例 建立一个链表存放学生信息-建立链表,#define LEN sizeof(struct stu)struct stu int num;int age;struct stu*next;struct stu*creat(int n)struct stu*head,*pf,*pb;int i;for(i=0;inum,例 查找与输出链表中的数据,struct stu*search(struct stu*h
16、ead,int n)struct stu*p;int i;p=head;while(p-num!=n,例在链表中插入一个结点,struct stu*insert(struct stu*head,struct stu*pi)struct stu*pf,*pb;pb=head;if(head=NULL)/*空表插入*/head=pi;pi-next=NULL;elsewhile(pi-numpb-num)/*找插入位置*/,if(pi-numnum)if(head=pb)head=pi;/*在第一结点之前插入*/else pf-next=pi;/*在其它位置插入*/pi-next=pb;elsep
17、b-next=pi;pi-next=NULL;/*在表末插入*/return head;,例从链表中删除一个结点,struct stu*delete(struct stu*head,int num)struct stu*pf,*pb;if(head=NULL)/*如为空表,输出提示信息*/printf(nempty list!n);goto end;pb=head;while(pb-num!=num/*pf指向当前结点,pb指向下一结点*/,if(pb-num=num)if(pb=head)head=pb-next;/*如找到被删结点,且为第一结点,则使head指向第二个结点,否则使pf所指结
18、点的指针指向下一结点*/else pf-next=pb-next;free(pb);printf(The node is deletedn);elseprintf(The node not been foud!n);end:return head;,例:以下程序运行后的输出结果是_。#include struct NODE int num;struct NODE*next;main()struct NODE*p,*q,*r;p=(struct NODE*)malloc(sizeof(struct NODE);q=(struct NODE*)malloc(sizeof(struct NODE);
19、r=(struct NODE*)malloc(sizeof(struct NODE);p-num=10;q-num=20;r-num=30;p-next=q;q-next=r;printf(%dn,p-num+q-next-num);A)10 B)20 C)30 D)40,D,例:若以下定义:struct link int data;struck link*next;a,b,c,*p,*q;且变量a和b之间已有如下图所示的链表结构:指针p指向变量a,q指向变量c。则能够把c插入到a和b 之间并形成新的链表的 语句组是_ a b data next data next p c data next
20、 q A)a.next=c;c.next=b;B)p.next=q;q.next=p.next;C)p-next=,D,例:假定建立了以下链表结构,指针p、q分别指向如图所示 的结点,则以下可以将q所指结点从链表中删除并释放该 结点的语句组是 _ A)free(q);p-next=q-next;B)(*p).next=(*q).next;free(q);C)q=(*q).next;(*p).next=q;free(q);D)q=q-next;p-next=q;p=p-next;free(p);,data next,data next,data next,head,p,q,B,9.6 共用体构造
21、数据类型,也叫联合体用途:使几个不同类型的变量共占一段内存(相互覆盖)共用体类型定义定义形式:,union 共用体名 类型标识符 成员名;类型标识符 成员名;.;,例 union data int i;char ch;float f;,类型定义不分配内存,形式一:union data int i;char ch;float f;a,b;,形式二:union data int i;char ch;float f;union data a,b,c,*p,d3;,形式三:union int i;char ch;float f;a,b,c;,共用体变量的定义,共用体变量定义分配内存,长度=最长成员所占
22、字节数,共用体变量任何时刻只有一个成员存在,共用体变量引用引用方式:,例 a.i=1;a.ch=a;a.f=1.5;printf(%d,a.i);(编译通过,运行结果不对),引用规则不能引用共用体变量,只能引用其成员,共用体变量中起作用的成员是最后一次存放的成员,例 union int i;char ch;float f;a;a=1;(),不能在定义共用体变量时初始化,例 union int i;char ch;float f;a=1,a,1.5;(),可以用一个共用体变量为另一个变量赋值,例 float x;union int i;char ch;float f;a,b;a.i=1;a.ch
23、=a;a.f=1.5;b=a;()x=a.f;(),结构体与共用体区别:存储方式不同,联系:两者可相互嵌套,例 结构体中嵌套共用体,struct char name10;int num;char sex;char job;union int class;char position10;category;person2;,1枚举类型的定义 enum 枚举类型名 取值表;例如,enum weekdays Sun,Mon,Tue,Wed,Thu,Fri,Sat;枚举变量的定义与结构变量类似(1)间接定义例如,enum weekdays workday;(2)直接定义例如,enum weekdays
24、Sun,Mon,Tue,Wed,Thu,Fri,Sat workday;说明(1)枚举型仅适应于取值有限的数据。例如,根据现行的历法规定,周天,年个月。(2)取值表中的值称为枚举元素,其含义由程序解释。例如,不是因为写成“Sun”就自动代表“星期天”。事实上,枚举元素用什么表示都可以。,9.7 枚举类型,(3)枚举元素作为常量是有值的定义时的顺序号(从开始),所以枚举元素可以进行比较,比较规则是:序号大者为大!例如,上例中的Sun=0、Mon=1、Sat=6,所以MonSun、Sat最大。(4)枚举元素的值也是可以人为改变的:在定义时由程序指定。例如,如果enum weekdays Sun=,
25、Mon,Tue,Wed,Thu,Fri,Sat;则Sun=,Mon=,从Tue=2开始,依次增。,#include stdio.h main()enum weekday sun,mon,tue,wed,thu,fri,sat a;scanf(%d,例 枚举举例,9.8 用typedef定义类型,typedef可以定义新的类型名来代替已有的类型名.,简单的名字代替:typedef int INTEGER;INTEGER a,b;,定义一个类型名代表一个结构体:typedef struct STUDENT;STUDENT studend1,student2,*p;,练习题1、设有如下定义:struct skint a;float b;data;Int*p;若要使p指向data中的成员a,正确的赋值语句是()。A.p=,