1第7章其他自定义数据类型北京科技大学计算机系C语言程序设计2020/1/192第7章结构体与共用体主要内容7.1构造数据类型概述7.2结构体类型7.3共用体类型7.4枚举类型7.5类型重命名7.6案例分析2020/1/193一个学生的信息有学号、姓名、性别、年龄、住址、成绩等。一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等。如何描述这些类型不同的相关数据?7.1构造数据类型概述信息管理结构体——一种构造类型数据结构体由若干不同类型的数据项组成,构成结构体的各个数据项称为结构体成员。2020/1/194struct结构体名{数据类型1成员名1;数据类型2成员名2;……数据类型n成员名n;};7.2结构体类型7.2.1结构体与结构体类型的定义结构体类型定义的一般形式:struct为关键字;结构体名是用户定义的类型标识。{}中是组成该结构体的成员。成员的数据类型可以是C语言所允许的任何数据类型。2020/1/195例如图书类型的定义:structbookcard{charnum[10];/*图书分类编号是字符数组类型*/charname[30];/*书名是字符数组类型*/charauthor[30];/*作者是字符数组类型*/charpublisher[60];/*出版社是字符数组类型*/floatprice;/*价格是单精度实型*/intn;/*库存量是整型*/};7.2结构体类型7.2.1结构体与结构体类型的定义2020/1/196例如学生类型的定义:structstudent{charnum[8];/*学号是字符数组类型*/charname[30];/*姓名是字符数组类型*/charsex;/*性别是字符型*/intage;/*年龄是整型*/charaddr[60];/*住址是字符数组类型*/intscore[6];/*成绩是整型数组类型*/};7.2结构体类型7.2.1结构体与结构体类型的定义2020/1/1977.2结构体类型7.2.2结构体变量的定义、引用与初始化1.结构体类型变量的定义利用已定义的结构体类型名定义变量struct结构体名变量名表;例如:structbookcardbook1[100];structstudents[30],t1,t2;结构体变量的各个成员在内存中占用连续存储区域,结构体变量所占内存大小为结构体中每个成员所占用内存的长度之和。structstudentnum8个字节name30个字节sex1个字节age4个字节addr60个字节score24个字节2020/1/198类型与变量是不同的概念。应先定义一个结构体类型,而后再定义结构体变量。系统对类型不分配空间,仅对变量分配空间。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。成员也可以是结构体变量。对结构中的成员,可以单独使用,它的作用与地位相当于普通变量。成员名可与程序中的变量名相同,也可与不同结构体类型的成员名相同,二者代表不同的对象。structdate{intyear,month,day;};structstudent{charnum[8];charname[30];charsex;structdatebirthday;/*成员为结构体类型*/charaddr[60];intscore[6];};7.2结构体类型结构体类型与变量的说明num8个字节name30个字节sex1个字节birthdayyear4个字节month4个字节day4个字节addr60个字节score24个字节2020/1/1997.2.2结构体变量的定义、引用与初始化1.结构体类型变量的定义在定义结构体类型的同时定义变量例如:structstudent{charnum[8],name[20],sex;intage;floatscore;}st[30];struct结构体名{成员定义表;}变量名表;2020/1/19101.结构体类型变量的定义直接定义结构体类型变量例如:struct{charnum[8],name[20],sex;intage;floatscore;}st[30],a,b,c;struct{成员定义表;}变量名表;7.2.2结构体变量的定义、引用与初始化2020/1/19112.结构体变量的初始化【例7-4】结构体变量的初始化。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={“40826011,Liming,'M',{1991,2,9},87.5},b={“40826025,Zhangqiang,'F',{1990,5,12},85},c;如果初值个数少于结构体成员个数,则将无初值对应的成员赋以0值。如果初值个数多于结构体成员个数,则编译出错。7.2.2结构体变量的定义、引用与初始化2020/1/19122.结构体变量的初始化【例7-5】结构体数组的初始化。structs{charnum[8],name[20],sex;floatscore;}stu[3]={{“40826011,Liming,'M',87.5},{“40826025,Zhangqiang,‘F',85},{“40826032,Wangxinping,'F',90}};元素的个数可以省略,根据赋初值时结构体常量的个数确定数组元素的个数7.2.2结构体变量的定义、引用与初始化2020/1/19133.结构体变量的运算用sizeof运算符计算结构体变量所占内存空间structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;sizeof(a)的结果为8+20+1+12+4=45sizeof(structstudent)的结果为457.2.2结构体变量的定义、引用与初始化2020/1/19143.结构体变量的运算同类型结构体变量之间的赋值运算结构体变量之间进行赋值时,系统将按成员一一对应赋值。structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a={“40826011,Liming,'M',{1977,12,9},87.5},b,c;c=a;7.2.2结构体变量的定义、引用与初始化2020/1/19153.结构体变量的运算对结构体变量进行取址运算structdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;对结构体变量a进行&a运算,可以得到a的首地址,它是结构体类型指针。7.2.2结构体变量的定义、引用与初始化2020/1/19164.结构体变量成员的引用结构体变量成员引用的一般形式:结构体变量名.成员名结构体变量a的各成员可分别表示为a.num、a.name、a.sex、a.birthday、a.scorestructdate{intyear,month,day;};structstudent{charnum[8],name[20],sex;structdatebirthday;floatscore;}a;“.”是分量运算符,运算级别最高。a.birthday.yeara.birthday.montha.birthday.day结构体变量的各个成员可进行何种运算,由该成员的数据类型决定7.2.2结构体变量的定义、引用与初始化2020/1/1917【例7-6】编写一个统计选票的程序。structcandidate{charname[20];/*name为候选人姓名*/intcount;/*count为候选人得票数*/}list[]={{invalid,0},{Zhang,0},{“Wang,0},{“Li,0},{“Zhao,0},{“Liu,0}};7.2.2结构体变量的定义、引用与初始化2020/1/1918main(){inti,n;printf(Entervote\n);scanf(%d,&n);/*输入所投候选人编号,编号从1开始*/while(n!=-1)/*当输入编号为-1时,表示投票结束*/{if(n=1&&n=5)list[n].count++;/*有效票,则相应候选人计票成员加1*/else{printf(invalid\n);list[0].count++;}/*无效票,list[0]的计票成员加1*/scanf(%d,&n);/*输入所投候选人编号*/}7.2.2结构体变量的定义、引用与初始化2020/1/1919for(i=1;i=5;i++)printf(%s:%d\n,list[i].name,list[i].count);printf(%s:%d\n,list[0].name,list[0].count);}7.2.2结构体变量的定义、引用与初始化2020/1/19207.2结构体类型1.结构体指针变量的定义结构体指针变量定义的一般形式:struct结构体名*指针变量名;structdate{intyear,month,day;}*q;例如:structstudent*p;p是指向structstudent结构体变量的指针变量7.2.3结构体的指针2020/1/19217.2.3结构体的指针2.结构体成员的三种引用形式用结构体变量名的引用形式:d.yeard.monthd.daystructdate{intyear,month,day;}d,*p=&d;用结构体指针变量的引用形式:(*p).year(*p).month(*p).dayp-yearp-monthp-day“-”是指向结构体成员运算符,优先级为一级p=&d.year×2020/1/1922【例】输入今天的日期,然后输出该日期。main(){structdate/*在函数中定义结构体类型*/{intyear,month,day;}today,*p=&today;/*定义结构体变量及其指针*/printf(Entertodaydate(YYYY/MM/DD):);scanf(%d/%d/%d,&today.year,&today.month,&today.day);printf(Today:%d/%d/%d\n,p-year,p-month,p-day);}7.2.3结构体的指针Entertodaydate(YYYY/MM/DD):2006/06/23Today:2006/6/232020/1/19233.指向结构体数组的指针【例7-7】利用结构体指针输出一组化学元素名称及其原子量。structlist{inti;charname[4];floatw;}tab[4]={{1,H,1.008},{2,He,4.0026},{3,Li,6.941},{4,Be,9.01218}};tab数组1Htab[0]1.0082Hetab[1]4.00263Litab[2]6.9414Betab[3]9.012187.2.3结构体的指针2020/1/19243.指向结构体数组的指针main(){structlist*p;printf(No\tName\tAtomicWeight\n);for(p=tab;ptab+4;p++)printf(%d\t%s\t%f\n,p-i,p-name,p-w);}tab数组1Htab[0]1.0082Hetab[1]4.00263Litab[2]6.9414Betab[3]9.01218pppppNoNameAtomicWeight1H1.0082He4.00263Li6.9