《高级语言程序设计C-结构体共用体枚举类型.ppt》由会员分享,可在线阅读,更多相关《高级语言程序设计C-结构体共用体枚举类型.ppt(47页珍藏版)》请在三一办公上搜索。
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;char sex;int a
2、ge;float score;char addr30;struct student stu1,stu2;,结构体变量的声明先定义结构体类型,再定义结构体变量一般形式:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 变量名表列;,定义结构体类型的同时定义结构体变量一般形式:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.变量名表列;,例 struct student int num;char name20;char sex;int age;float score;char addr30;stu1,stu2;,直接定义结构体变量一般
3、形式:,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 Lin”,M,19,“200 Beijing Road”;,形式二:,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.结构体变量=初始数据;,例 struct stude
5、nt 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 Lin”,M,19,“200 Beijing Road”;,11.2 结构体数组结构体数组的定义三种形式:,形式一:struct student int num;char
6、 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;stu=,;,顺序初始化:struct student int num;char name20;char sex;int age;struct student stu
7、=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=,;,结构体数组引用,引用方式:结构体数组名下标.成员名,例 统计候选人选票,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);fo
8、r(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);,11.3 结构体和指针指向结构体变量的指针定义形式:struct 结构体名*结构体指针名;例 struct student*p;,使用结构体指针变量引用成员形式,存放结构体变量在内存的起始地址,指向运算符优先级:1结合方向:从左向右,例 指向结构体的指针变量,main()struct student long int num;char name20;c
9、har sex;float score;stu_1,*p;p=,例 int n;int*p=n=10,struct student stu1;struct student*p=(*p).num=101,指向结构体数组的指针,例 指向结构体数组的指针,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*p;for(p=stu;pnum,p-name,p-sex,p-age);,
10、用指向结构体的指针作函数参数用结构体变量的成员作参数-值传递用指向结构体变量或数组的指针作参数-地址传递用结构体变量作参数-多值传递,效率低,struct data int a,b,c;main()void 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,
11、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);printf(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);,copy,例 用结构体变量作函数参数,struct data int a,b,c;main()void func(struct
12、data*parm);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(,例 用结构体指针变量作函数参数,链表是指将若干个数据项按一定的原则连接起来的表。链表中每一个数据称为节点。链表连接的原则是:前一个节点指向下一个节点;而且只有通过前一个节点才能找到下一个节点。链表是一种常见的重要的数据结构。利用它可以实现动态地进行存储分配。,11.4 链表,1249,h,1094,1021,头
13、指针,单向链表结构,空地址,1094,1021,NULL,struct stu int num;float score;a,b,c;,一、简单链表的建立与输出,struct stu*next;,struct stu*h;,a.num=101;,a,b,c,101,a.score=98.5;,98.5,b.num=102;,b.score=67.8;,102,67.8,c.num=103;,c.score=88.5;,103,88.5,struct stu int num;float score;a,b,c;,struct stu*next;,struct stu*h;,a.num=101;,a
14、,b,c,101,a.score=98.5;,98.5,b.num=102;,b.score=67.8;,102,67.8,c.num=103;,c.score=88.5;,103,88.5,h=,h,a.next=,b.next=,c.next=NULL;,NULL,形成链表,struct stu*p;,a,b,c,101,98.5,102,67.8,103,88.5,h,NULL,p,p=h;,for(;),p=(*p).next,printf(“%d,%fn”,(*p).num,(*p).score);,p!=NULL;,p,p,printf(“%d,%fn”,p-num,p-score
15、);,二、动态链表的建立与输出,所谓动态链表的建立是指在程序执行过程中从无到有地建立一个链表,即一个一个地开辟节点和输入各节点数据,并建立起前后相链的关系。,动态分配存储空间函数,int*p1;p1=(int*)malloc(2);,p1=(int*)malloc(int);,p1=malloc(float);,malloc(),p1,类型说明符*malloc(unsigned int size);,在内存中开辟指定大小(size)的存储空间,并将返回此存储空间的起始地址。,p1=(struct stu*)malloc(sizeof(struct stu);,struct stu int nu
16、m;float score;struct stu*next;*p1;,p1=(float*)malloc(sizeof(float);,为强制类型转换。即将由malloc 函数得到的地址值转换成一个浮点类型存储单元的地址值。,为字节数运算符,在此是用来说明该指针变量将要开辟的是非字符类型的动态内存。,p1,动态分配存储空间函数,calloc(),类型说明符*calloc(unsigned,unsigned size);,在内存中开辟若干(n)个指定大小(size)的存储空间,并将分配的单元清零,返回该空间的首地址。,char*p=(char*)calloc(4,20);,void free(v
17、oid*ptr);,在内存中释放指定(ptr)的存储空间。,p=(long*)malloc(8)free(p);,h,p1,struct stu int num;float score;struct stu*next;*h,*p1,*p2;,p1=(struct stu*)malloc(sizeof(struct stu);,h=p1;,p1=(struct stu*)malloc(sizeof(struct stu);,p1,h.next=p1;,p2=p1;,p2,p1=(struct stu*)malloc(sizeof(struct stu);,p1,p2.next=p1;,p2=p1
18、;,p2,h,p1,struct stu int num;float score;struct stu*next;*h,*p1,*p2;,NULL,main()int i;,p2=p1=(struct stu*)malloc(sizeof(struct stu);,p2=p1;,*p2,p2,for(i=1;i2;i+),p2-next=p1;,scanf(“%d,%fn”,h=p1;,scanf(“%d,%fn”,p2-next=NULL;,p1=(struct stu*)malloc(sizeof(struct stu);,h,p1,struct stu int num;float sco
19、re;struct stu*next;*h,*p1,*p2;,NULL,main(),*p2,struct stu*p1=h;,printf(“%d,%f n”,p1-num,p1-score);,p1=p1-next;,p1,while(p1!=NULL),输出链表的操作,h,NULL,三、动态链表的删除操作,动态链表的删除操作是指将一个节从一个已有的链表中删除。,main()int num;scanf(”%d”,struct stu int num;float score;struct stu*next;*h,*p1,*p2;,h,NULL,查找欲删结点,找到结点进行删除,p1,p2,p1
20、,p2,h,NULL,四、动态链表的插入操作,动态链表的插入操作是指将一个节点插入到一个已有的链表中。,x,p1,struct stu int num;float score;struct stu*next;*h,*p1,*p2;,NULL,main(),*p2,scanf(“%d,%f”,p2=p1;,p0=,struct stu*p0,x;,x,p2,p0,while(p0-nump1-num&(p1-next!=NULL),p1=p1-next;,p2-next=p0;,p0-next=p1;,p1,p2,p1,h,构造数据类型,也叫联合体用途:使几个不同类型的变量共占一段内存(相互覆盖
21、)共用体类型定义定义形式:,union 共用体名 类型标识符 成员名;类型标识符 成员名;.;,例 union data int i;char ch;float f;,类型定义不分配内存,11.5 共用体,形式一: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=a;a.f=1.5;b=a;()x=a.f;(),结构
23、体与共用体区别:存储方式不同,联系:两者可相互嵌套,结构体中嵌套共用体,struct int num;char name20;char sex;char job;union int class;char position10;category;person2;,scanf(%c,一种变量,只可能具有少数几个数值,可以一一列举这些数值,并分别用符号名字来表示这些数值,这样的变量,称为枚举类型的变量。例:表示颜色、星期、状态值的变量。,11.6 枚举类型,11.6 枚举类型,1.枚举类型定义:enum 枚举类型名 枚举值 1=整常数 1,枚举值 n=整常数 n;,enum weekday Sun,
24、Mon,Tue,Wed,Thu,Fri,Sat;enum weekday workday,week_end;enum color red,green,blue bkcolor,textcolor;enum color linecolor;enum off,on status;,Sun、red 等称为枚举元素或枚举常量,系统把枚举元素作为整常数处理,每个枚举元素对应一个整常数,类型声明中省略=整常数 时,第一个枚举元素为 0,后续枚举元素顺序加 1。,enum weekday Sun,Mon=-2,Tue,Wed,Thu,Fri,Sat;避免这种情况 0-2-1 0 1 2 3 enum wee
25、kday Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat;,2.枚举变量的引用,1)只能用枚举元素对枚举变量进行赋值 例:workday=Mon;textcolor=red;2)计算机把枚举元素的值当为整常数处理 例:enum weekday Sun,Mon,Tue,Wed,Thu,Fri,Sat;enum weekday workday=Sun;printf(“%d”,workday);输出结果:0,3.枚举变量的值用来作为比较判断的情况,if(status=on)switch(workday)case Sun:case Mon:,编制一个程序。当输入今天的星期序号后,输出明
26、天是星期几。,enum weekday Mon=1,Tue,Wed,Thu,Fri,Sat,Sun;char*name8=error,Mon,Tue,Wed,Thu,Fri,Sat,Sun;,main()enum weekday d;printf(Input todays numeral(1-7):);scanf(%d,enum weekday Mon=1,Tue,Wed,Thu,Fri,Sat,Sun;char*name8=error,Mon,Tue,Wed,Thu,Fri,Sat,Sun;,用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预编译时处理 编译时处理简单字符置换 为已有类型命名,11.7,