第7章结构和链表7.1结构类型和结构变量7.2结构数组7.3结构与函数7.4链表7.5联合7.6位域7.7枚举7.8类型定义7.9变量定义17.1结构类型和结构变量基本类型:如整型、实型、字符型等。构造类型:数组,每个元素都是属于同一个类型。结构类型:不同的数据类型组成一个整体方便引用。例如:一个学生数据实体可能有以下多项信息学号、姓名、性别、年龄、成绩、家庭地址intcharcharintfloatchar说明:这类实体的数据因所包含的成员类型不同,不能用单个数组来表示,也不便将它们的成员分拆成多个独立的简单变量,因为这样会失去实体的整体性。21.结构类型结构类型形式:struct结构类型名{成员说明表};其中关键字“struct”:引出结构类型的定义。结构类型名:结构类型的标记,用来定义引用该结构的结构变量。成员说明表:指明该结构类型的各成员的数据类型和名称。每个成员的说明形式为:类型成员名;3结构类型例【例】学生基本信息的结构类型:structstudent{intnumber;/*学号*/charname[20];/*姓名,设姓名少于20个字符*/charsex;/*性别*/charaddress[40];/*家庭地址*/};说明:在C++中,如果不会引起混淆(例如,结构类型与结构变量同名),引用结构类型可以不用struct引导。4嵌套的结构类型当结构类型中的某个成员又是另一个结构类型时,这种结构类型是一种嵌套的结构类型。例如,给上述学生信息增加出生日期,并将出生日期定义为一种包含日、月、年3项信息的结构类型,则更完整的学生信息类型就被定义成嵌套的结构类型。5嵌套的结构类型例structDate/*说明一个日期*/{intday;/*日*/intmonth;/*月*/intyear;/*年*/};structstudent{intnumber;/*学号*/charname[20];/*姓名*/charsex;/*性别*/Datebirthday;/*采用C++句法,birthday的类型是结构类型Date,如果采用C句法,则在Date之前用struct引导*/charaddress[40];/*家庭地址*/};62.结构变量在结构类型定义中,详细列出了结构类型所包含的每个成员的名称及其类型。实际上,结构类型定义只是表明一类实体其数据属性的“模式”,并不定义一个特定的数据实体,因此不要求分配存储单元。程序如果要实际使用结构类型所描述的数据信息,就必须定义结构变量。结构变量要占用存储单元,能存放如结构类型所描述的具体数据。对结构类型和结构变量,我们可以简单地理解为,结构类型是表示数据框架的描述文本,结构变量才能存放实际数据。7结构变量的定义一、先定义结构类型,再声明结构变量形式:struct结构类型名结构变量名表;/*C句法*/结构类型名结构变量名表;//C++句法例如:利用前面已定义的结构类型student声明结构变量代码:structstudentst1,st2;/*C句法*/studentst1,st2;//C++句法其中:student为结构类型名,st1和st2为结构变量。说明:结构变量声明后,每个结构变量的成员名称、成员个数和各成员的数据类型与结构类型定义中的成员名称、成员个数和各成员的数据类型相一致。8结构变量内存分配单元变量名numbernamesexbirthdayaddressdaymonthyearst110001ZhangpingM2011198515NanjingRdst210002LiyingF08041986100BeijinRd9结构变量的定义二、在定义结构类型的同时声明结构变量10一般形式:struct结构类型名{成员说明表}结构变量表;例如:structstuSType{intnumber;/*学号*/charname[20];/*姓名*/intscore;/*成绩*/}stuS;结构变量初始化在定义结构变量的同时给它赋初值,称为结构变量的初始化。结构变量初始化时,要按结构类型定义中成员的顺序逐一给出各成员的初值。例如:structpoint/*说明绘图程序的坐标类型*/{intx;inty;}p1={20,50},p2;/*p1的x值为20,p1的y值为50*/说明:也可以在定义结构类型与声明结构变量分开的情况下,在声明结构变量时进行初始化。例如:structpointp3={10,40},p4={20,50};11结构变量初始化说明1.要注意结构类型名和结构变量名的区别。不能对结构类型名进行赋值、存取或运算,因为类型不占用存储空间;而结构变量会占用存储空间,定义时可以赋初值,定义后可引用。2.结构变量初始化的时间。静态的和全局的结构变量初始化在程序执行之前完成,静态的结构变量未指定初值时,值自动置0。局部结构变量初始化是程序控制每次进入它所属辖域时创建并初始化,未指定初值的局部结构变量其初值是不确定的。12结构变量初始化说明3.可以定义指向结构的指针变量(结构指针变量简称结构指针)。例如:structDate*pd,date3;/*定义变量*/pd=&date3;/*pd指向date3*/表示:定义结构指针pd和结构变量date3,并使结构指针pd指向结构变量date3,即结构指针pd的内容为结构变量date3所占据的存储块的首地址。133.结构变量的引用一、引用结构变量1.用结构变量名直接引用结构变量例如:structstudent{intnumber;/*学号*/charname[20];/*姓名*/floatscore;/*成绩*/}st1={10001,Zhangping,85.0},st2;st2=st1;/*将结构变量st1作为整体赋值给结构变量st2*/说明:两个结构变量必须是同类型的。143.结构变量的引用2.指向结构变量的指针间接引用结构变量例如:structstudent{intnumber;/*学号*/charname[20];/*姓名*/floatscore;/*成绩*/}st1={10001,Zhangping,85.0},st2;student*p1=&st1;/*定义结构指针变量p1,并指向结构变量st1的首地址*/153.结构变量的引用二、引用结构成员1.使用结构变量和成员运算符引用方法:结构变量名.成员名其中:点符号“.”是结构的成员运算符,是优先级最高运算符之一。假设有前面定义的类型为stuSType的结构变量stuS例如:stuS.name/*直接引用stuS结构变量的name成员*/163.结构变量的引用引用结构变量的成员无非是对该成员进行输入输出、赋值、运算等操作。例如:printf(学号:%d姓名:%s成绩:%d\n,stuS.number,stuS.name,stuS.score);/*输出学生stuS的信息*/代码:stuS.score+=5;/*更新学生stuS的成绩*/strcpy(stuS.name,Liming);/*更正学生stuS的姓名*/17二、引用结构成员2.使用结构指针和指针运算符引用方法:指针变量名-成员名其中:“-”是指针运算符,它是由减号“-”和大于号“”两个字符组成(请注意中间不能有空格符),其优先级与成员运算符“.”一样,也是优先级最高的运算符之一。继续使用前面定义的结构变量stuS,可以使用结构指针间接引用stuS结构变量的成员。stuSType*sp=&stuS;/*定义指向结构变量stuS的结构指针sp*/sp-number=10002;/*修改学号*/sp-score=95;/*修改成绩*/18二、引用结构成员3.使用结构指针和成员运算符引用方法:(*指针变量名).成员名其中:圆括号是必要的。若省略,由于成员运算符“.”优先级高于“*”,将会导致编译错误。例如:stuSType*sp=&stuS;/*采用C++句法,定义结构指针sp指向结构stuS*/(*sp).score=95;/*与代码sp-score=95;等价*/*sp.score=95;/*错误的写法,变成*(sp.score)=95;*/19引用结构变量或成员注意(1)不能直接对结构变量进行输入或输出,只允许对结构变量的成员变量进行输入和输出。例如,对于前面定义的类型为student的结构变量st1,以下分别是错误和正确的代码:printf(%s,st1);/*错误,st1是结构变量不能直接输出*/printf(%s,st1.name);/*正确,仅输出st1的name成员*/20引用结构变量或成员注意(2)如果结构中的成员本身也是一个结构类型,在引用该成员的成员时需使用多个成员运算符“.”,将嵌套的结构成员一级一级地连续指定。例如,想引用前面定义的类型为student的结构变量st1中成员birthday成员year,正确的写法是:st1.birthday.year21【例7.1】利用结构变量,输入3个学生的姓名、语文成绩和数学成绩,然后计算每个学生的平均成绩并输出。#includestdio.hstructstuScore/*定义结构*/{charname[20];intchinese;intmath;};voidmain(){floataver1,aver2,aver3;stuScorest1,st2,st3;/*采用C++句法,定义3个结构变量*/printf(请输入3位学生的姓名、语文成绩、数学成绩\n);scanf(%s%d%d,st1.name,&st1.chinese,&st1.math);scanf(%s%d%d,st2.name,&st2.chinese,&st2.math);scanf(%s%d%d,st3.name,&st3.chinese,&st3.math);22【例7.1】程序续aver1=(st1.chinese+st1.math)/2.0;/*计算平均成绩*/aver2=(st2.chinese+st2.math)/2.0;aver3=(st3.chinese+st3.math)/2.0;printf(姓名\t语文\t数学\t平均成绩\n);printf(%s\t%4d\t%4d\t%6.2f\n,st1.name,st1.chinese,st1.math,aver1);printf(%s\t%4d\t%4d\t%6.2f\n,st2.name,st2.chinese,st2.math,aver2);printf(%s\t%4d\t%4d\t%6.1f\n,st3.name,st3.chinese,st3.math,aver3);}237.2结构数组从例7.1中可以看出,一个结构变量只能存放一个学生的基本信息。如果要描述两个学生的信息需要有两个结构变量,依此类推,当要描述一个班级的学生时,独立定义同样类型的许许多多结构变量的方法显然是不可取的。在C程序设计中,一般用结构类型描述个体的信息结构,用数组表示个体的集合。当数组的元素是结构时,这种数组就称为结构数组。例如,用结构数组表示一个班级学生,数组的元素存储一个学生的有关信息。这样,能充分反映班级的整体性,程序处理也变得更为方便。241.结构数组的定义定义结构数组与定义结构变量的方法类似也有两种方法。(1)先定义结构类型,再声明结构数组structstuScore{charname[20];intchinese;intmath;};stuScorest[3];25(2)在定义结构类型的同时声明结构数组structstuScore{charname[20];intchinese;intmath;}st[3];结构数组的初始化与结构变量初始化相仿,在定义结构数组时,也可给结构数组赋初值。例如:structstuScore{charname[20];intchinese;intmath;}st[3]={{Zhang,80,85},{Li,85,90},{Wang,90,70}};26namechinesmathst[0]Zhan