《结构体联合体.ppt》由会员分享,可在线阅读,更多相关《结构体联合体.ppt(40页珍藏版)》请在三一办公上搜索。
1、第11章 结构体与联合体,11.1 结构体结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-自定义数据类型结构体类型定义,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;,成员类型可以是基本型或构造型,struct是关键字,不能省略,合法标识符可省:无名结构体,例 struct student int num;char name20;char sex;int age;float score;char addr30;,结构体类型定义描述结构的组织形式,不分配内存,结构体类型定义的作用域,例 struct student int num;char name20;ch
2、ar sex;int age;float score;char addr30;struct student stu1,stu2;,11.2 结构体变量的定义先定义结构体类型,再定义结构体变量一般形式:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 变量名表列;,例#define STUDENT struct student STUDENT int num;char name20;char sex;int age;float score;char addr30;STUDENT stu1,stu2;,定义结构体类型的同时定义结构体变量一般形式:,str
3、uct 结构体名 类型标识符 成员名;类型标识符 成员名;.变量名表列;,例 struct 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、变量:分配内存类型:不能赋值、存取、运算;变量:可以结构体可嵌套结构体成员名与程序中变量名可相同,不会混淆结构体类型及变量的作用域与生存期,11.3 结构体变量的引用引用规则 结构体变量不能整体引用,只能引用变量成员,可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用,成员(分量)运算符优先级:1结合性:从左向右,引用方式:结构体变量名.成员名,11.4 结构体变量的初始化形式一:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 结构体变量=初始数据;,例 struct student int num;char name20;char s
5、ex;int age;char addr30;struct student stu1=112,“Wang 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 in
6、t num;char name20;char sex;int age;char addr30;stu1=112,“Wang Lin”,M,19,“200 Beijing Road”;,11.5 结构体数组结构体数组的定义三种形式:,形式一: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 a
7、ge;stu2;,结构体数组初始化,例 struct int num;char name20;char sex;int age;stu=,;,顺序初始化: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=,;,结构体数组引用,引用方式:结构体数组名下标.成员名,例 统计候选
8、人选票,struct person char name20;int count;leader3=“Li”,0,“Zhang”,0,”Wang“,0;main()int i,j;char leader_name20;for(i=1;i=10;i+)scanf(%s,leader_name);for(j=0;j3;j+)if(strcmp(leader_name,leaderj.name)=0)leaderj.count+;for(i=0;i3;i+)printf(%5s:%dn,leaderi.name,leaderi.count);,struct data int a,b,c;main()vo
9、id func(struct data);struct data arg;arg.a=27;arg.b=3;arg.c=arg.a+arg.b;printf(arg.a=%d arg.b=%d arg.c=%dn,arg.a,arg.b,arg.c);printf(Call Func().n);func(arg);printf(arg.a=%d arg.b=%d arg.c=%dn,arg.a,arg.b,arg.c);void func(struct data parm)printf(parm.a=%d parm.b=%d parm.c=%dn,parm.a,parm.b,parm.c);p
10、rintf(Process.n);parm.a=18;parm.b=5;parm.c=parm.a*parm.b;printf(parm.a=%d parm.b=%d parm.c=%dn,parm.a,parm.b,parm.c);printf(Return.n);,例 用结构体变量作函数参数,链表,C语言中,变量存储空间的分配分为静态分配和动态分配。,静态存储分配:,先在程序说明部分进行变量的说明,然后在程序编译时分配适当的存储单元。这些存储单元一经分配,在它的生存期内是固定不变的。,动态存储分配:,在程序执行期间,通过“申请”分配指定的存储空间来存储数据,当有闲置不用的存储空间时,又可以
11、随时将其释放。,ANSI C标准为动态分配系统定义了三个函数:malloc、calloc、free。,用户可以通过调用C语言的标准库函数来实现动态存储分配,从而得到或释放指定数目的内存空间。,这些函数在头文件alloc.h及stdlib.h中声明。,2.链表存储结构是一种动态数据结构,特点:,(1)它包含的数据对象的个数及其相互关系可以按需要改变.,(2)存储空间是程序根据需要在程序运行过程中向系统申请获得.,(3)不要求逻辑上相邻的元素在物理位置上也相邻.,(4)没有顺序存储结构所具有的弱点.,以上链表结构中只有一个方向的指针,因此又称为单链表,简称为链表。,一般地,用户可根据链表存放的信息
12、如存放学生信息就称为学生链表,存放职工信息就称为职工链表。,在单链表,通常称它的数据元素为结点,每个结点都是一个结构体,至少包括两个成员:存储数据元素信息的成员称为数据域;存储直接后继结点存储位置的成员称为指针域.,显然,链表结点的指针域存放的地址类型与它自身的类型是相同的。,这就是C语言中较为特殊的递归结构体或自引用结构体,这种结构体是指向自身结构体的指针。,每个链表都有一个“头指针”head,整个链表的访问必须从头指针开始进行,头指针指示链表中的第一个结点的存储位置,习惯上将“头指针”head指示的链表简称为链表head,下同。同时,由于最后一个数据元素没有直接后继结点,则链表中最后一个结
13、点的指针为“空”(NULL,即空地址)。,数据元素之间的逻辑关系是由结点中的指针指示的,逻辑上相邻的两个数据元素其存储的物理位置不要求紧邻,即链表中的数据元素在内存中不是顺序存放的,要访问其数据元素不能像数组一样按下标去查找。要找一个元素,必须先找到上一个元素,根据上一个元素的指针域才能找到下一个元素。,因此,链表的数据元素访问必须从头指针开始,逐个访问链表的每个结点,直到元素的指针域为空为止。,要使用链表,首先应定义结点的类型,再定义相应的结构体变量。例如,前面链表中结点的结构类型可以定义为:struct student char name10;struct student*next;其中,
14、next为指针变量,其类型为结构体类型student,它可存储一个student结构体类型变量的地址,即实现链表中指向下一个结点的指针域。,这是一个递归定义,它在结构体student的定义未完成时又引用它定义其它的变量(指针变量)。,引入链表后,用户就可以根据需要在程序的运行过程中动态分配存储空间。动态存储分配需要利用以下C语言库函数。,(1)函数malloc,函数功能:,函数原型:,void*malloc(unsigned int size);,在内存的动态存储区中分配一个长度为size的连续存储空间。其中,形参size为无符号整数,是函数malloc要求分配存储空间的字节个数。函数返回值为
15、一个指针,它指向所分配存储空间的起始地址。若函数返回值为0,则表示未能成功申请到内存空间。函数类型为void,表示返回的指针不指向任何具体的类型.,int*p;long*lp;p=(int*)malloc(8);lp=(long*)malloc(12);head=(struct student*)malloc(sizeof(struct student);,例如:malloc(8);,通过函数malloc向系统申请8个字节的内存空间,其起始地址通过函数值返回。若要求用一个指针变量(具有某种类型)指向这个起始地址,则需要显式进行类型转换。例如:,(2)函数calloc 函数原型:,void ca
16、lloc(unsigned int n,unsigned int size);,函数功能:,在内存的动态存储区域中分配n个长度为size的连续存储空间。函数的返回值为分配域的起始地址;如果分配不成功,则返回值为0。,例如:,int*p;,p=(int*)calloc(3,8);,分配3个8字节的的连续存储空间,并将其起始地址赋给整型指针p。,(3)函数free,函数原型:,void free(void*ptr);,函数功能:,释放由指针变量ptr为所指示的内存区域。其中,ptr一个指针变量,指向最近一次调用函数malloc或calloc时所分配的连续存储空间的首地址。通过函数free将已分配的
17、内存区域交还系统,使系统可以重新对其进行分配。,例如:,long*p;,p=(long*)malloc(8);,.free(p);,例:动态分配一块区域,输入一个学生数据#include“string.h”#include“stdlib.h”main()struct stu int num;char name20;float score;*ps;ps=(struct stu*)malloc(sizeof(struct stu);psnum=102;strcpy(psname,”zhang ping”);psscore=62.5;printf(“Number=%dnName=%snScore=%
18、.2fn”,psnum,psname,psscore);free(ps);,例:写一函数,建立学生成绩单链表。从键盘输入每个学生的学号,姓名和成绩。当输入的学号为负数时,输入结束并返回链表的头指针。,Struct stu*creat()struct stu*head;Struct stu*last,*p;Int num;Char name20;Float score;Head=last=NULL;Printf(“please input num name score:n”);Scanf(“%d%s%f”,Struct stuInt num;Char name20;Float score;Str
19、uct stu*next;,p,11.8 联合体用途:使几个不同类型的变量共占一段内存(相互覆盖)联合体类型定义定义形式:,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;,联合体变量的定义,联合体变量定义
20、分配内存,长度=最长成员所占字节数,联合体变量任何时刻只有一个成员存在,联合体变量引用引用方式:,例 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
21、f;a,b;a.i=1;a.ch=a;a.f=1.5;b=a;()x=a.f;(),例 将一个整数按字节输出,运行结果:i=60501ch0=101,ch1=141ch0=A,ch1=a,main()union int_char int i;char ch2;x;x.i=24897;printf(i=%on,x.i);printf(ch0=%o,ch1=%on ch0=%c,ch1=%cn,x.ch0,x.ch1,x.ch0,x.ch1);,枚举类型,所谓枚举,是将具有相同属性的一类数据值一一列举。,一.枚举类型的定义,1.enum 枚举类型名 标识符1,标识符2,标识符n;,enum是枚举类
22、型定义的关键字,枚举类型名是用户命名的标识符,它与enum构成枚举类型的标识符,花括号中“标识符1,标识符2,标识符n”是所定义枚举类型的全部取值,通常称这些标识符为“枚举元素“或“枚举常量”。这些标识符是用户定义的标识符,一般是所代表事物的名称,但这些标识符并不自动地代表事物本身。,例如,enum colorred,blue,green,black;,用户可根据需要在定义时直接指定某一枚举元素的编号,从而改变量系统默认的编号。例如:enum week sun=7,mon,tue=2,wed,thu,fri,sat;则sun的序号为7,mon的序号为8,tue的序号为2,wed的序号为3,th
23、u的序号为4,fri的序号为5,sat的序号为6。,2.枚举类型是有序类型,一般地,枚举类型中各枚举元素按定义时的先后次序分别编号为0、1、2、.、n-1。,例如:,redblue 值为真,各枚举元素可根据其序号进行大小比较和相应的运算,green-red,值为2,二.枚举类型的应用,1枚举类型变量的定义,enum male,femalesex1,sex2;,先定义枚举类型,再定义枚举类型变量,enum weeksun,mon,tue,wed,thu,fri,sat;enum week weekday,workday;,定义枚举类型的同时定义枚举变量,enum color red,blue,g
24、reen,blacka,b,c;,直接定义枚举变量,例:编写程序,输入今天是星期几,计算并输出明天是星期几Enum weeksun,mon,tur,wed,thu,fri,satEnum week tomorrow(day)Enum day;int n;n=(int)day+1)%7;Return(enum week)n);Main()enum week day1,day2;Char*name=“sum”,”mon”,”tur”,”wed”,”fri”,”sat”;Int n;Printf(“n请输入06内的整数:”);Scanf(”%d”,请输入06内的整数:3明天是:thu,自定义类型(用
25、typedef定义类型)功能:用自定义名字为已有数据类型命名类型定义简单形式:typedef type name;,例 typedef int INTEGER;,类型定义语句关键字,已有数据类型名,用户定义的类型名,例 typedef float REAL;,类型定义后,与已有类型一样使用,例 INTEGER a,b,c;REAL f1,f2;,说明:1.typedef 没有创造新数据类型2.typedef 是定义类型,不能定义变量3.typedef 与 define 不同,define typedef预编译时处理 编译时处理简单字符置换 为已有类型命名,typedef定义类型步骤按定义变量方
26、法先写出定义体 如 int i;将变量名换成新类型名 如 int INTEGER;最前面加typedef 如 typedef int INTEGER;用新类型名定义变量 如 INTEGER i,j;,例 定义结构体类型 struct date int month;int day;int year;d;,例 定义结构体类型 struct date int month;int day;int year;DATE;,例 定义结构体类型typedef struct date int month;int day;int year;DATE;,例 定义结构体类型 DATE birthday,*p;,struct date int month;int day;int year;birthday,*p;,