复杂构造数据类型2复杂构造数据类型结构体共用体枚举类型3引入对于同种类型的数据可以用数组来描述。在解决实际问题时,有时需要将多个不同数据类型的数据组合在一起表达一个整体的信息。如学生个人信息,包括姓名、学号、年龄等,就包含了字符数组和整型数据。4结构体学生成绩表学号姓名语文数学英语总分1001周炎7862672071002王林8773862461003丁鹏6585932431004李娟688281231………………在一条记录中既有整型数据(学号、分数等),又有字符串(姓名),像这样的数据是由几种不同类型的数据构成,是不能用前面学过的数组来表示的,因为数组的各个元素都是相同的数据类型。按照以前所学的数据类型是无法处理这种复杂数据的。为了解决这种问题,C语言将几种不同类型的数据组合到一起,这就是我们下面要介绍的结构体类型。55.1.1结构体的引出及使用(1)结构体的定义:由若干个不同类型的数据项组成的组合类型,在C语言中叫做结构体类型。格式:struct结构类型名{类型名1成员名表1;类型名2成员名表2;……类型名n成员名表n;};(1)结构体类型用struct关键字定义(2)花括号里的每一项称为结构体成员(3)结构体成员的类型可以是普通的数据类型(如int、char等),也可以是数组、指针或已经定义的结构体等任意的数据类型。注意此处“;”不能省略6例如:职工的基本信息有以下几部分组成:编号、姓名、性别、年龄、班组、基本工资、奖金、保险、实发工资。分析:可以将每个工人的信息定义为一个结构体类型,设类型名是workerstructworker{intnum;charname[20];charsex;intage;charbranch[20];floatpay;floatbonus;floatinsurance;floatrealpay;};7注意:结构体类型的定义并没有在内存中为其分配空间,仅仅定义了数据的组织形式,创立了一种数据类型,可以理解为以前学过的int、char等基本数据类型。只有在定义了结构体类型的变量后,才会在内存中为该变量分配空间。在为结构体变量分配存储空间时,每个结构体变量所占存储空间大小为其成员所占存储空间的总和。结构体类型在使用之前应先定义其类型结构,然后再定义该类型变量,才能使用。structworker{intnum;charname[20];charsex;intage;charbranch[20];floatpay;floatbonus;floatinsurance;floatrealpay;};共占2+20+1+2+20+4+4+4+4=61个字节8(2)定义结构体类型变量的方法前面定义的worker同int、char等一样只是类型的名字,不是结构体变量,不能直接使用,需由此类型继续定义结构体变量才能使用。步骤:先定义一个结构体类型,再定义变量。struct结构体类型名变量名列表;注意:关键字struct与结构体类型标识符一起使用。例:structworkerw1,w2,w[50];也可以在定义类型的同时定义结构体变量。还可以直接定义结构体变量structworker{intnum;charname[20];charsex;intage;charbranch[20];floatpay;floatbonus;floatinsurance;floatrealpay;}w1,w2,w[50];struct{intnum;charname[20];charsex;intage;charbranch[20];floatpay;floatbonus;floatinsurance;floatrealpay;}w1,w2,w[50];注意:不出现类型名9定义了结构体变量后,系统为之分配内存单元,结构体的各成员在内存中是按顺序连续存放的,所以结构体变量在内存中占据的字节数是各个成员的长度和。可用求类型长度运算符求出sizeof(类型名)如:sizeof(int)为2sizeof(structworker)为61;定义结构体变量必须指明具体的类型名,不同于定义int等标准数据类型变量,因为不同的结构体类型具有不同的结构组成。structw1,w2;×10(3)结构体变量的引用一般来说,在程序设计中不直接引用结构体变量,而是引用结构体变量的某个成员变量。成员的引用形式:结构体变量名.成员名structstudent{intnum;charname[10];charsex;intage;structbirthbirthday;floatscore;charaddr[20];}stu1;stu1.num=9002;gets(stu1.name);stu1.sex='m';printf(“%d,%c”,stu1.num,stu1.sex);11结构体变量使用说明:结构体变量通常不能整体使用,不能整体输入、输出,只能对单个成员分别引用。但当结构体变量作为函数参数或赋初值时,可以整体使用;或者两个相同类型的结构体变量,如果一个已经赋值,可以对另外一个整体赋值。如果student1已被赋值,则可以:student2=student1;12结构体成员也可以是另一个结构体变量,如前面的birthday成员本身又是birth类型的结构体变量,这个成员也不能整体赋值,要用若干个成员运算符引用。stu1.birthday.month=4;stu1.birthday.day=5;stu1.birthday.year=1998;例如:structbirth{intmonth;intday;intyear;};structstudent{intnum;charname[10];charsex;intage;structbirthbirthday;floatscore;charaddr[20];}stu1;13(4)结构体变量的初始化可以在定义结构体变量的同时,对其初始化例:structstudent{longintnum;charname[20];charsex;charaddr[20];}a={9001,曹名,'m',123北京路};相当于:a.num=9001;strcpy(a.name,“曹名”);a.sex=‘m’;strcpy(a.addr,“123北京路”);145.1.2结构体数组的引出及使用结构体数组中每一个数组元素都是一个结构体类型的数据,它们都分别包括各个成员项,例如一个班级的40名同学信息组成的数组,每一个同学的数据都是一个结构体类型。例:structstudent{intnum;charname[20];charsex;floatscore;charaddr[20];};structstudentstu[40];struct{intnum;charname[20];charsex;floatscore;charaddr[20];}stu[40];15结构体数组各元素在内存中是连续存放的,各元素的成员也是按顺存放的。numnamesexscoreaddrStu[0]10101LiLinM87.5103BeijingStu[1]10102ZuFengF98130ShanghaiStu[2]10103WangMiM78104Jinan…………16结构体数组的初始化例structstudent{intnum;charname[20];charsex;floatscore;charaddr[20];}stu[3]={{10101,”LiLin”,’M’,87.5,”103Beijing”},{10102,”ZuFeng”,’F’,98,”130Shanghai”},{10103,”WangMi”,’M’,78,”104Jinan”}};175.1.4结构体与指针1.指向结构体变量的指针structstudent{longnum;charname[20];charsex;floatscore;}stu1,*p;p=&stu1;(*p).num=89101;/*相当于:stu1.num=89101;*/strcpy((*p).name,LiLin);/*相当于:strcpy(stu1.name,“LiLin);*/(*p).sex='M';/*相当于:stu1.sex='M';*/(*p).score=89;/*相当于:stu1.score=89;*/注:(1)此处*p相当于结构体变量(2)(*p).表示成员引用,()不能省略,因为成员运算符优先级最高。(3)可以用指向运算符来引用成员,例如可以用p-num来代替(*p).num183种引用结构体成员的方法⑴结构体变量.成员名⑵(*p).成员名⑶p-成员名分析以下几种运算符:p-np-n++++p-n*p.num(错误!)应改为:(*p).num192.指向结构体数组的指针structstudent{intnum;charname[20];charsex;floatscore;};structstudentstu[3],*p;……for(p=stu;pstu+3;p++)printf(“%d,%s,%c,%f”,p-num,p-name,p-sex,p-score);stu[0]stu[1]stu[2]p10101LiLinM87.510102ZuFengF9810103WangMiM78p++后指向什么位置?注意:p是指向结构体数组的元素的,不能用来指向数组元素中的某一成员,如p=&stu[1].num是错误的。215.3共用体在某些实际问题中,所定义的两个结构体类型中只有一个或很少数的成员不同,其它大部分成员都是一样的,这样如果使用两类结构,会发现有大部分的程序代码是重复的。能否设计一种新数据类型,使属性相同的成员在同一结构里,而属性不同的成员随机可用?C语言提供了一种新的结构类型——共用体类型,可以解决这个问题。221.共用体的概念所谓“共用体”类型,是指使几个不同类型的变量共同占用同一段内存单元。232.共用体的定义例1:uniondata{inti;charch;floatf;}aa,bb,cc;union共用体类型名{类型标识符1成员名1;类型标识符2成员名2;…..…….类型标识符n成员名n;};共用体类型的变量声明形式也有3种,同结构体类型。24例2:uniondata{inti;charch;floatf;};uniondataaa,bb;例3:union{inti;charch;floatf;}aa,bb,cc;25共用体变量所占内存的长度等于最长的成员的长度。而不是各成员的长度之和,这一点不同于结构体。例如前面的例子data类型的变量aa,占据的内存空间为4个字节,而不是2+1+4=7个字节。共用体变量所占的内存空间263.共用体变量的引用共用体变量只能引用它的成员,不能引用共用体变量本身。共用体变量.成员名例如前例中的变量aa,可以引用它的成员aa.i=56;aa.f=123.6432;aa.ch=‘A’;如下使用是错误的:printf(“%d”,aa);274.共用体类型数据的特点(1)每一瞬时只能存放其中的一个成员,而不是同时存放几种,即其它成员不起作用。(2)只有最后一个存放的成员的值有效,其他成员将失去原值。如上例中的变量aa只有最后一个成员值aa.ch=‘A’是有效的。(3)共用体变量的地址和它的成员地址都是同一地址。即&aa和&aa.i、&aa.ch、&aa.f的起始地址都是一样的。(4)共用体变量不能初始化,也不能对变量名整体赋值,不能引用变量名来输出一个值,只能引用它的某个成员。28(5)共用体变量不能作为函数的参数,也不能作为函数返回值。但可以使用指向共用体变量的指针。(6)共用体类型可以出现在结构体中,共用体成员也可以是结构体类型。(7)可以定义共用体数组。29例设有若干个人员的数据,其中有学生和教师。学生的数据包括:姓名、号码、性别、职业、班级。教师的数据包