《第6章结构体与共用体.ppt》由会员分享,可在线阅读,更多相关《第6章结构体与共用体.ppt(99页珍藏版)》请在三一办公上搜索。
1、1,第6章 结构体与共用体,C/C+语言程序设计,主讲教师:贾澎涛,2023/9/5,2,第6章 结构体与共用体,6.1 结构体6.2 共用体6.3 枚举类型与类型命名,2023/9/5,3,一个学生的信息有学号、姓名、性别、年龄、住址、成绩等。一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等。如何描述这些类型不同的相关数据?,6.1 结构体,6.1.1 结构体与结构体类型的定义,?,信息管理,结构体一种构造类型数据 结构体由若干不同类型的数据项组成,构成结构体的各个数据项称为结构体成员。,2023/9/5,4,struct 结构体名 数据类型1 成员名1;数据类型2 成
2、员名2;数据类型n 成员名n;,6.1 结构体,6.1.1 结构体与结构体类型的定义,结构体类型定义的一般形式:,struct为关键字;结构体名是用户定义的类型标识。中是组成该结构体的成员。成员的数据类型可以是C语言所允许的任何数据类型。,2023/9/5,5,例如图书类型的定义:struct bookcard char num10;/*图书分类编号是字符数组类型*/char name30;/*书名是字符数组类型*/char author30;/*作者是字符数组类型*/char publisher60;/*出版社是字符数组类型*/float price;/*价格是单精度实型*/int n;/*
3、库存量是整型*/;,例如学生类型的定义:struct student char num8;/*学号是字符数组类型*/char name30;/*姓名是字符数组类型*/char sex;/*性别是字符型*/int age;/*年龄是整型*/char addr60;/*住址是字符数组类型*/int score6;/*成绩是整型数组类型*/;,6.1 结构体,6.1.1 结构体与结构体类型的定义,2023/9/5,6,6.1 结构体,6.1.2 结构体变量的定义与初始化,1.结构体类型变量的定义,利用已定义的结构体类型名定义变量 struct 结构体名 变量名表;例如:struct bookcard
4、 book1100;struct student s30,t1,t2;,按照结构体类型的组成,系统为定义的结构体变量分配内存单元。结构体变量的各个成员在内存中占用连续存储区域,结构体变量所占内存大小为结构体中每个成员所占用内存的长度之和。,2023/9/5,7,6.1 结构体,结构体类型与变量的说明,类型与变量是不同的概念。应先定义一个结构体类型,而后再定义结构体变量。系统对类型不分配空间,仅对变量分配空间。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。,成员也可以是结构变量。,对结构中的成员,可以单独使用,它的作用与地位相当于普通变量。成员名可与程序中的变量名相同时,也可与不
5、同结构体类型的成员名相同,二者代表不同的对象。,struct date int year,month,day;struct student char num8;char name30;char sex;struct date birthday;/*成员为结构体类型*/char addr60;int score6;,2023/9/5,8,6.1 结构体,6.1.2 结构体变量的定义与初始化,1.结构体类型变量的定义,在定义结构体类型的同时定义变量,例如:struct student char num8,name20,sex;int age;float score;st30;,struct 结构体
6、名 成员定义表;变量名表;,2023/9/5,9,6.1 结构体,6.1.2 结构体变量的定义与初始化,1.结构体类型变量的定义,直接定义结构体类型变量,例如:struct char num8,name20,sex;int age;float score;st30,a,b,c;,struct 成员定义表;变量名表;,2023/9/5,10,6.1 结构体,6.1.2 结构体变量的定义与初始化,2.结构体变量的初始化,【例6.4】结构体变量的初始化。struct date int year,month,day;struct student char num8,name20,sex;struct
7、date birthday;float score;a=9606011,Li ming,M,1977,12,9,83,b=9608025,Zhang liming,F,1978,5,10,87,c;,如果初值个数少于结构体成员个数,则将无初值对应的成员赋以0值。如果初值个数多于结构体成员个数,则编译出错。,2023/9/5,11,6.1 结构体,6.1.2 结构体变量的定义与初始化,2.结构体变量的初始化,【例6.5】结构体数组的初始化。struct s char num8,name20,sex;float score;stu3=9606011,Li ming,M,87.5,9606012,Z
8、hang jiangguo,M,79,9606013,Wang ping,F,90;,元素的个数可以省略,根据赋初值时结构体常量的个数确定数组元素的个数,2023/9/5,12,6.1 结构体,6.1.2 结构体变量的定义与初始化,3.结构体变量的运算,用sizeof运算符计算结构体变量所占内存空间,struct date int year,month,day;struct student char num8,name20,sex;struct date birthday;float score;a;,sizeof(a)的结果为8+20+1+6+4=39 sizeof(struct stude
9、nt)的结果为39,2023/9/5,13,6.1 结构体,6.1.2 结构体变量的定义与初始化,3.结构体变量的运算,同类型结构体变量之间的赋值运算,结构体变量之间进行赋值时,系统将按成员一一对应赋值。,struct date int year,month,day;struct student char num8,name20,sex;struct date birthday;float score;a=9606011,Li ming,M,1977,12,9,83,b,c;c=a;,2023/9/5,14,6.1 结构体,6.1.2 结构体变量的定义与初始化,3.结构体变量的运算,对结构体变
10、量进行取址运算,struct date int year,month,day;struct student char num8,name20,sex;struct date birthday;float score;a;,对结构体变量a进行&a 运算,可以得到a的首地址,它是结构体类型指针。,2023/9/5,15,6.1 结构体,6.1.2 结构体变量的定义与初始化,4.结构体变量成员的引用,结构体变量成员引用的一般形式:结构体变量名.成员名,结构体变量a的各成员可分别表示为a.num、a.name、a.sex、a.birthday、a.score,struct date int year,
11、month,day;struct student char num8,name20,sex;struct date birthday;float score;a;,“.”是分量运算符,运算级别最高。,a.birthday.yeara.birthday.montha.birthday.day,结构体变量的各个成员可进行何种运算,由该成员的数据类型决定,2023/9/5,16,6.1 结构体,6.1.2 结构体变量的定义与初始化,【例6.6】编写一个统计选票的程序。struct candidate char name20;/*name为候选人姓名*/int count;/*count为候选人得票数
12、*/list=invalid,0,Zhao,0,Qian,0,Sun,0,Li,0,Zhou,0;,2023/9/5,17,6.1 结构体,6.1.2 结构体变量的定义与初始化,main()int i,n;printf(Enter voten);scanf(%d,/*输入所投候选人编号*/,2023/9/5,18,6.1 结构体,6.1.2 结构体变量的定义与初始化,for(i=1;i=5;i+)printf(%s:%dn,listi.name,listi.count);printf(%s:%dn,list0.name,list0.count);,2023/9/5,19,6.1 结构体,1.结
13、构体指针变量的定义,结构体指针变量定义的一般形式:struct 结构体名*指针变量名;,struct date int year,month,day;*q;,例如:struct student*p;,p是指向struct student结构体变量的指针变量,6.1.3 结构体的指针,2023/9/5,20,6.1 结构体,6.1.3 结构体的指针,2.结构体成员的三种引用形式,用结构体变量名的引用形式:d.year d.month d.day,struct date int year,month,day;d,*p=,用结构体指针变量的引用形式:(*p).year(*p).month(*p).d
14、ay p-year p-month p-day,“-”是指向结构体成员运算符,优先级为一级,p=&d.year,2023/9/5,21,6.1 结构体,6.1.3 结构体的指针,【例6_a】输入今天的日期,然后输出该日期。main()struct date/*在函数中定义结构体类型*/int year,month,day;today,*p=,2023/9/5,22,6.1 结构体,6.1.3 结构体的指针,3.指向结构体数组的指针,【例6.7】利用结构体指针输出一组化学 元素名称及其原子量。struct list int i;char name4;float w;tab4=1,H,1.008,
15、2,He,4.0026,3,Li,6.941,4,Be,9.01218;,2023/9/5,23,6.1 结构体,6.1.3 结构体的指针,3.指向结构体数组的指针,main()struct list*p;printf(NotNametAtomic Weightn);for(p=tab;pi,p-name,p-w);,No Name Atomic Weight,1 H 1.008,2 He 4.0026,3 Li 6.941,4 Be 9.01218,2023/9/5,24,6.1 结构体,6.1.3 结构体的指针,【例6.8】分析自增自减运算对程序结果的影响。struct code int
16、i;char c;a=100,A,200,B,300,C,400,D;,2023/9/5,25,6.1 结构体,6.1.3 结构体的指针,main()struct code*p=a;printf(%dt,+p-i);printf(%ct,(+p)-c);printf(%dt,(p+)-i);printf(%ct,+p-c);printf(%dt,p-i+);printf(%dn,p-i);,p,101,D,301,101,B,200,D,300,301,2023/9/5,26,6.1 结构体,6.1.4 函数间结构体数据的传递,方法一:在函数之间直接传递结构体数据。函数的形参定义为结构体变量。
17、函数调用时,可将主调函数的结构体类型实参传递给被调函数的形参。如果将函数定义为结构体类型函数,可利用return语句将一个结构体数据结果返回到主调函数中。,2023/9/5,27,6.1 结构体,6.1.4 函数间结构体数据的传递,方法二:在函数之间传递结构体指针。形参定义为指向结构体类型的指针变量,可将主调函数的结构体指针传递给被调函数的形参变量,通过指针形参的指向域的扩展,操作主调函数中结构体变量及其成员。如果将函数定义为结构体指针型函数,可利用return语句将被调函数中结构体变量的指针返回给主调函数的结构体指针变量。方法三:利用全局结构体变量传递结构体数据。,2023/9/5,28,6
18、.1 结构体,6.1.4 函数间结构体数据的传递,【例6.6】编制一个复数乘法函数,采用值传递的方 法传送数据。struct complex/*定义存放复数的结构体类型*/float re;/*re成员用于存放复数的实部*/float im;/*im成员用于存放复数的虚部*/;,2023/9/5,29,6.1 结构体,6.1.4 函数间结构体数据的传递,struct complex multiplier(struct complex cx,struct complex cy)struct complex cz;cz.re=cx.re*cy.re-cx.im*cy.im;cz.im=cx.re*
19、cy.im+cx.im*cy.re;return(cz);,形参是结构体变量。调用此函数时,系统将分别为形参cx和cy各分配一个sizeof(struct complex)大小的内存空间,每个成员都要一一传递。,2023/9/5,30,6.1 结构体,6.1.4 函数间结构体数据的传递,main()struct complex x,y,z;x.re=3.2;x.im=1.5;y.re=2.7;y.im=4.6;z=multiplier(x,y);printf(%f+%fin,z.re,z.im);/*以复数形式输出*/,2023/9/5,31,6.1 结构体,6.1.4 函数间结构体数据的传递
20、,【例6.10】编制一个复数乘法函数,采用传递指针 的方法达到传送数据的目的。struct complex float re,im;void multiplier(struct complex*px,struct complex*py,struct complex*pz)pz-re=px-re*py-re-px-im*py-im;pz-im=px-re*py-im+px-im*py-re;,形参定义为指针型参数。函数调用时,实参传递的是结构体指针(地址),因此形参px、py可读取主调函数中变量的内容,乘积结果也可通过形参pz指针存到主调函数中的目标变量。这样实参与形参之间的数据传递由多值(每个
21、成员的值)变成了单值(结构体变量的首地址)。,2023/9/5,32,6.1 结构体,6.1.4 函数间结构体数据的传递,main()struct complex x,y,z;x.re=3.2;x.im=1.5;y.re=2.7;y.im=4.6;multiplier(,2023/9/5,33,链表是一种动态数据结构,可根据需要动态地分配存储单元。在数组中,插入或删除一个元素都比较繁琐,而用链表则相对容易。但是数组元素的引用比较简单,对于链表中结点数据的存取操作则相对复杂。,6.1 结构体,6.1.5 结构体的应用链表,链表中每个元素称为一个结点。构成链表的结点必须是结构体类型数据。,1.链表
22、的基本结构,相邻结点的地址不一定是连续的,依靠指针将 它们连接起来。,struct nodechar c;struct node*next;,2023/9/5,34,C语言提供了相关的存储管理库函数。这里仅介绍其中三个,它们的原型说明在“stdlib.h”头文件和“alloc.h”头文件中,使用这三个函数时,应选择其中一个头文件包含到源程序中。,动态分配存储区函数malloc()函数原型:void*malloc(unsigned size);调用格式:malloc(size)功能:在内存分配一个size字节的存储区。调用 结果为新分配的存储区的首地址,是一个void 类型指针。若分配失败,则返
23、回NULL(即0)。,6.1 结构体,6.1.5 结构体的应用链表(选学内容),2.动态分配和释放存储单元,在ANSI C标准中,关键字void有两种用法。第一种用法,可将无返回值的函数定义为void类型第二种用法,用void*定义指针,这是一个指向非具体数据类型的指针,称为无类型指针。,2023/9/5,35,【例6.11】调用malloc函数分配所需存储单元。#include main()struct st int n;struct st*next;*p;p=(struct st*)malloc(sizeof(struct st);p-n=5;p-next=NULL;printf(p-n=
24、%dtp-next=%xn,p-n,p-next);,6.1 结构体,6.1.5 结构体的应用链表,2.动态分配和释放存储单元,将函数返回值转换成结构体指针,2023/9/5,36,动态分配存储区函数calloc()函数原型:void*calloc(unsigned int n,unsigned int size);调用格式:calloc(n,size)功能:在内存分配一个n倍size字节的存储区。调用结果为新分配的存储区的首地址,是一个void类型指针。若分配失败,则返回NULL(即0)。,6.1 结构体,6.1.5 结构体的应用链表,2.动态分配和释放存储单元,2023/9/5,37,【例
25、6.12】调用calloc函数分配所需存储单元。#include main()int i,*ip;ip=(int*)calloc(10,2);for(i=0;i10;i+)scanf(%d,ip+i);for(i=0;i10;i+)printf(%d,*(ip+i);printf(n);,6.1 结构体,6.1.5 结构体的应用链表,2.动态分配和释放存储单元,动态分配了10个存放整型数据的存储单元,2023/9/5,38,释放动态分配存储区函数free()函数原型:void free(void*p);,6.1 结构体,6.1.5 结构体的应用链表,2.动态分配和释放存储单元,此函数无返回值,
26、实参必须是一个指向动态分配存储区的指针,它可以是任何类型的指针变量。,调用格式:free(p)功能:释放p所指向的动态分配的存储区。,2023/9/5,39,建立链表就是根据需要一个一个地开辟新结点,在结点中存放数据并建立结点之间的链接关系。,【例6.13】建立一个学生电话簿的单向链表函数。,6.1 结构体,6.1.5 结构体的应用链表,3.建立单向链表,2023/9/5,40,strcpy(p-name,name);/*为新结点中的成员赋值*/printf(tel:);gets(p-tel);p-next=NULL;if(h=NULL)/*h为空,表示新结点为第一个结点*/h=p;/*头指针
27、指向第一个结点*/else/*h不为空*/q-next=p;/*新结点与尾结点相连接*/q=p;/*使q指向新的尾结点*/printf(name:);gets(name);return h;,struct node*create()static struct node*h;struct node*p,*q;char name20;h=NULL;printf(name:);gets(name);while(strlen(name)!=0)/*当输入的姓名不是空串循环*/p=NEW;/*开辟新结点*/if(p=NULL)/*p为NULL,新结点分配失败*/printf(Allocation fai
28、luren);exit(0);/*结束程序运行*/,#include#include#define NEW(struct node*)malloc(sizeof(struct node)struct node char name20,tel9;struct node*next;,6.1 结构体,6.1.5 结构体的应用链表,main()struct node*head;head=create();,2023/9/5,41,【例6.14】输出学生电话簿链表函数。,6.1 结构体,6.1.5 结构体的应用链表,4.输出单向链表中各结点信息,2023/9/5,42,void prlist(struc
29、t node*head)struct node*p;p=head;while(p!=NULL)printf(%st%sn,p-name,p-tel);p=p-next;,#include#include#define NEW(struct node*)malloc(sizeof(struct node)struct node char name20,tel9;struct node*next;,6.1 结构体,6.1.5 结构体的应用链表,main()struct node*head;head=create();prlist(head);,2023/9/5,43,在链表中,如果要删除第i个结点
30、,一般是将第(i-1)个结点直接与第(i+1)个结点相连接,然后再释放第i个结点的存储单元。,6.1 结构体,6.1.5 结构体的应用链表,5.删除单向链表中指定的结点,2023/9/5,44,【例6.15】删除学生电话簿链 表中指定学生的信息。,6.1 结构体,6.1.5 结构体的应用链表,删除第一个结点,删除中间结点或尾结点,学生姓名,当姓名不同并且不是尾结点循环,2023/9/5,45,【例6.15】删除学生电话簿链表中指定学生的信息。,6.1 结构体,6.1.5 结构体的应用链表,(a)删除第一个结点(head=p-next),2023/9/5,46,【例6.15】删除学生电话簿链表中
31、指定学生的信息。,6.1 结构体,6.1.5 结构体的应用链表,(b)删除中间结点或尾结点(q-next=p-next),2023/9/5,47,【例6.15】删除学生电话簿链表中指定学生的信息。,6.1 结构体,6.1.5 结构体的应用链表,(c)未找到指定的结点(strcmp(x,p-name)!=0),2023/9/5,48,if(strcmp(x,p-name)=0)if(p=head)head=p-next;/*删除头结点*/else q-next=p-next;/*删除中间或尾结点*/free(p);/*释放被删除的结点*/else printf(Not found.);/*未找到
32、指定的结点*/h=head;return h;,#include#include#define NEW(struct node*)malloc(sizeof(struct node)struct node char name20,tel9;struct node*next;,6.1 结构体,6.1.5 结构体的应用链表,2023/9/5,49,将一个新结点插入到链表中,首先要寻找插入的位置。如果要求在第i个结点前插入,可设置三个工作指针p0、p和q,p0是指向待插入结点的指针。利用p和q指针查找第i个结点,找到后再将新结点链接到链表上。,6.1 结构体,6.1.5 结构体的应用链表,6.在单向
33、链表中插入结点,q,q,新的第i个结点,2023/9/5,50,【例9.16】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。,6.1 结构体,6.1.5 结构体的应用链表,当姓名不同并且不是尾结点循环,空表时插入结点,在表尾追加结点,在表头插入结点,在表中间插入结点,2023/9/5,51,【例6.16】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。,6.1 结构体,6.1.5 结构体的应用链表,(a)在表头插入结点(head=p0;p0-next=p),20
34、23/9/5,52,【例6.16】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。,6.1 结构体,6.1.5 结构体的应用链表,(b)在表中间插入结点(q-next=p0;p0-next=p),2023/9/5,53,【例6.16】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。,6.1 结构体,6.1.5 结构体的应用链表,(c)在表尾追加结点(p-next=p0;p0-next=NULL),2023/9/5,54,if(strcmp(x,p-name)=0)
35、if(p=head)head=p0;/*在表头插入结点*/else q-next=p0;/*在表中间插入结点*/p0-next=p;else p-next=p0;/*在表尾插入结点*/p0-next=NULL;h=head;return h;,6.1 结构体,6.1.5 结构体的应用链表,#include#include#define NEW(struct node*)malloc(sizeof(struct node)struct node char name20,tel9;struct node*next;,2023/9/5,55,6.1 结构体,6.1.5 结构体的应用链表,【例6.17
36、】学生电话簿链表管理程序。,编制此程序可利用例6.13至例6.16的4个函数完成链表的建立、输出、删除和插入等功能,这里只需编制一个main函数完成对这4个函数的调用。#include#define NEW(struct node*)malloc(sizeof(struct node)struct node char name20,tel9;struct node*next;,2023/9/5,56,6.1 结构体,6.1.5 结构体的应用链表,main()struct node*create(),*delnode(struct node*,char*);struct node*insert(
37、struct node*,struct node*,char*);void prlist(struct node*);struct node*head=NULL,*stu;char s80,name20;int c;,2023/9/5,57,6.1 结构体,6.1.5 结构体的应用链表,do do printf(n*MENU*n);printf(1.Create a list n);printf(2.Print a list n);printf(3.Delete a node n);printf(4.Insert a node n);printf(0.Quit n);printf(Enter
38、your choice(0-4):);gets(s);c=atoi(s);while(c4);,可以先选择1建立一个链表,然后根据需要选择功能2、功能3、功能4、直到选择0退出程序的运行,2023/9/5,58,6.1 结构体,6.1.5 结构体的应用链表,switch(c)case 1:head=create();break;case 2:prlist(head);break;case 3:printf(nInput a name deleted:n);gets(name);head=delnode(head,name);break;case 4:stu=NEW;printf(nInput
39、a new noden);printf(name:);gets(stu-name);printf(tel:);gets(stu-tel);stu-next=NULL;printf(nInsert positionn);printf(name:);gets(name);head=insert(head,stu,name);while(c);,2023/9/5,59,结构体类型解决了如何描述一个逻辑上相关,但数据类型不同的一组分量的集合。在需要节省内存储空间时,c语言还提供了一种由若干个不同类型的数据项组成,但共享同一存储空间的构造类型。,6.2 共用体(选学内容),6.2.1 共用体与共用体类型
40、的定义,共用体一种构造类型数据 共用体由若干不同类型的数据项组成,构成共用体的各个数据项称为共用体成员。,由于共享的特性,只有最新存储的数据是有效的。,2023/9/5,60,union 共用体名 数据类型1 成员名1;数据类型2 成员名2;数据类型n 成员名n;,6.2 共用体,6.2.1 共用体与共用体类型的定义,共用体类型定义的一般形式:,union为关键字;共用体名是用户定义的类型标识。中是组成该共用体的成员。成员的数据类型可以是C语言所允许的任何数据类型。,2023/9/5,61,例如:union utype int i;char ch;long l;char c4;,6.2 共用体
41、,6.2.1 共用体与共用体类型的定义,定义了一个union utype共用体类型,共用体类型定义不分配内存空间,只是说明此类型数据的组成情况。,2023/9/5,62,6.2 共用体,6.2.2 共用体变量的定义与初始化,1.共用体变量的定义,利用已定义的共用体类型名定义变量 union 共用体名 变量名表;例如:union utype u1,u2;,按照共用体类型的组成,系统为定义的共用体变量分配内存单元。共用体变量所占内存大小等于共用体中占用内存的长度最长的成员。,2023/9/5,63,6.2 共用体,6.2.2 共用体变量的定义与初始化,1.共用体变量的定义,在定义共用体类型的同时定
42、义变量,例如:union utype int i;char ch;long l;char c4;a,b,c;,union 共用体名 成员定义表;变量名表;,2023/9/5,64,6.2 共用体,6.2.2 共用体变量的定义与初始化,1.共用体变量的定义,直接定义共用体类型变量,例如:union int i;char ch;long l;char c4;a,b,c;,union 成员定义表;变量名表;,2023/9/5,65,6.2 共用体,6.2.2 共用体变量的定义与初始化,2.共用体变量的运算,用sizeof运算符计算共用体变量所占内存空间,union utype int i;char
43、ch;long l;char c4;a,b,c;,sizeof(a)的结果为4 sizeof(union utype)的结果为4,2023/9/5,66,6.2 共用体,6.2.2 共用体变量的定义与初始化,2.共用体变量的运算,同类型共用体变量之间的赋值运算,共用体变量之间进行赋值时,系统仅赋当前有效成员的值(即最新存储的数据)。,union utype int i;char ch;long l;char c4;a,*p=,对共用体变量进行取址运算,2023/9/5,67,6.2 共用体,6.2.2 共用体变量的定义与初始化,3.共用体变量成员的引用,共用体变量成员的引用有三种形式。,例如:
44、union u char u1;int u2;x,*p=,用共用体变量名的引用形式:x.u1 x.u2,用共用体指针变量的引用形式:(*p).u1(*p).u2 p-u1 p-u2,2023/9/5,68,6.2 共用体,6.2.2 共用体变量的定义与初始化,4.共用体变量赋初值,【例6.18】共用体变量赋初值。union u char u1;int u2;main()union u a=0 x9741;printf(1.%c%xn,a.u1,a.u2);a.u1=a;printf(2.%c%xn,a.u1,a.u2);,共用体类型变量在定义时只能对第一个成员进行赋初值。由于第一个成员是字符型
45、,用一个字节,所以对于初值0 x9741仅能接受0 x41,初值的高字节被截去。,1.A 41,2.a 61,2023/9/5,69,6.2 共用体,6.2.2 共用体变量的定义与初始化,main()union long n;int k;char c;un;un.n=0 x12345678;printf(%lxn,un.n);printf(%xn,un.k);printf(%xn,un.c);un.c=A;printf(%ldn,un.n);printf(%dn,un.k);printf(%cn,un.c);,12345678,5678,78,305416841,22081,A,2023/9/
46、5,70,enum是关键字;枚举名和枚举常量是标识符;枚举常量之间用逗号分隔。,例如:enum weekday Sun,Mon,Tue,Wed,Thu,Fri,Sat;enum color1 blue,green,red;enum flag false,true;,6.3 枚举类型与类型命名,6.3.1 枚举类型,1.枚举类型的定义,枚举类型定义的一般形式:enum 枚举名 枚举常量取值表;,枚举是一个具有有限个整型符号常量的集合,这些整型符号常量称为枚举常量。每个枚举类型都必须进行类型的定义,定义时必须将其所有的枚举常量一一列举,以便限定此枚举类型变量的取值范围。,2023/9/5,71,在
47、枚举类型中,每个枚举常量都代表一个整型值。在定义枚举类型的同时可隐式或显式地定义枚举常量所代表的值。,例如:enum weekday Sun,Mon,Tue,Wed,Thu,Fri,Sat;,6.3 枚举类型与类型命名,6.3.1 枚举类型,2.枚举常量的整型值,隐式定义:按照类型定义时枚举常量列举的顺序分别代表0、1、2、等整型值。,0,1,2,3,4,5,6,2023/9/5,72,例如:enum op plus=43,minus=45,multiply=42,divide=47;enum workday Mon=1,Tue,Wed,Thu,Fri;,6.3 枚举类型与类型命名,6.3.1
48、 枚举类型,2.枚举常量的整型值,显式定义:在定义类型的同时指定枚举常量的值,其中如有未指定值的枚举常量,则根据前面的枚举常量的值依次递增1。,2,3,4,5,2023/9/5,73,例如:enum flag fg;enum color1 c1;enum color2 blank,brown,yellow,white c2;enum lightblue,lightgreen,lightred c3;,6.3 枚举类型与类型命名,6.3.1 枚举类型,3.枚举变量的定义,枚举类型变量定义的三种形式:enum 枚举名 枚举变量名表;enum 枚举名 枚举常量取值表枚举变量表;enum 枚举常量取值
49、表枚举变量表;,2023/9/5,74,赋值运算 fg=true;c1=red;c2=yellow;c3=lightblue;c3=white;,6.3 枚举类型与类型命名,6.3.1 枚举类型,4.枚举数据的运算,用sizeof运算符计算枚举变量所占内存空间,枚举变量中存放的是整型值,每个枚举变量占用2个字节,是enum color2类型的枚举值,2023/9/5,75,取址运算 enum color2 blank,brown,yellow,white c2;enum flag fg;&c2、&fg,6.3 枚举类型与类型命名,6.3.1 枚举类型,4.枚举数据的运算,关系运算,truefa
50、lse SunSat,真(1)假(0),按枚举类型数据所代表的整型值进行比较,2023/9/5,76,在C系统中,不能直接对枚举数据进行输入和输出。由于枚举变量可以作为整型变量处理,所以可以通过间接方法输入输出枚举变量的值。,枚举变量的输出 方法一:直接输出枚举变量中存放的整型值。,6.3 枚举类型与类型命名,6.3.1 枚举类型,5.枚举数据的输入输出,枚举变量的输入,枚举变量作为整型变量进行输入。例如:scanf(%d,1,含义不直观,fg=true;printf(%d,fg);,2023/9/5,77,switch(fg)case false:printf(false);break;ca