学习目标掌握结构体和联合体的基本使用掌握结构体和联合体的区别了解两者嵌套概述C中,结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样,在使用结构变量时要先对其定义。定义结构变量的一般格式为:struct结构名{类型变量名;类型变量名;...}结构变量;结构体类型变量结构名是结构的标识符不是变量名。类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。构成结构的每一个类型变量称为结构成员,它象数组的元素一样,但数组中元素是以下标来访问的,而结构是按变量名字来访问成员的。下面举一个例子来说明怎样定义结构变量:结构体示例numnamesexageaddr10968Peter.Jman26wuxistructstudent{intnum;charname[20];charsex;intage;charaddr[30];};结构体类型变量structstring{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;}person;或structstring{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;};structstringperson;结构体类型变量如果需要定义多个具有相同形式的结构变量时用这种方法比较方便,它先作结构说明,再用结构名来定义变量。例如:structstringTianyr,Liuqi,...;如果省略结构名,则称之为无名结构,这种情况常常出现在函数内部,用这种结构时前面的例子变成:struct{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;}Tianyr,Liuqi;结构体变量引用结构是一个新的数据类型,因此结构变量也可以象其它类型的变量一样赋值、运算,不同的是结构变量以成员作为基本变量。结构成员的表示方式为:结构变量.成员名如果将结构变量.成员名看成一个整体,则这个整体的数据类型与结构中该成员的数据类型相同,这样就可象前面所讲的变量那样使用。下面这个例子定义了一个结构变量,其中每个成员都从键盘接收数据,然后对结构中的浮点数求和,并显示运算结果,同时将数据以文本方式存入一个名为wage.dat的磁盘文件中。请注意这个例子中不同结构成员的访问。#includestdio.hmain(){struct{/*定义一个结构变量*/charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;}a;FILE*fp;floatwage;charc='Y';fp=fopen(wage.dat,w);/*创建一个文件只写*/while(c=='Y'||c=='y')/*判断是否继续循环*/{printf(\nName:);scanf(%s,a.name);/*输入姓名*/printf(Age:);scanf(%d,&a.wage);/*输入年龄*/printf(Sex:);scanf(%d,a.sex);printf(Dept:);scanf(%s,a.depart);8•printf(Wage1:);•scanf(%f,&a.wage1);/*输入工资*/•printf(Wage2:);•scanf(%f,&a.wage2);•printf(Wage3:);•scanf(%f,&a.wage3);•printf(Wage4:);•scanf(%f,&a.wage4);•printf(Wage5:);•scanf(%f,&a.wage5);•wage=a.wage1+a.wage2+a.wage3+a.wage4+a.wage5;•printf(Thesumofwageis6.2f\n,wage);/*显示结果*/•fprintf(fp,%10s%4d%4s%30s%10.2f\n,/*结果写入文件*/•a.name,a.age,a.sex,a.depart,wage);•while(1)•{•printf(Continue?Y/N);•c=getchar();•if(c=='Y'||c=='y'||c=='N'||c=='n')•break;•}•}•fclose(fp);•}结构数组•结构数组就是具有相同结构类型的变量集合。假如要定义一个班级40个同学的姓名、性别、年龄和住址,可以定义成一个结构数组。如下所示:struct{charname[8];charsex[2];intage;charaddr[40];}student[40];•需要指出的是结构数组成员的访问是以数组元素为结构变量的,其形式为:结构数组元素.成员名例如:student[0].namestudent[30].age实际上结构数组相当于一个二维构造,第一维是结构数组元素,每个元素是一个结构变量,第二维是结构成员。注意:结构数组的成员也可以是数组变量。structa{intm[3][5];floatf;chars[20];}y[4];为了访问结构a中结构变量y[2]的这个变量,可写成y[2].m[1][4]结构指针•结构指针是指向结构的指针。它由一个加在结构变量名前的*操作符来定义,例如用前面已说明的结构定义一个结构指针如下:structstring{charname[8];charsex[2];intage;charaddr[40];}*student;也可省略结构指针名只作结构说明,然后再用下面的语句定义结构指针。structstring*student;结构指针使用结构指针对结构成员的访问,与结构变量对结构成员的访问在表达方式上有所不同。结构指针对结构成员的访问表示为:结构指针名-结构成员其中-是两个符号-和的组合,好象一个箭头指向结构成员。例如要给上面定义的结构中name和age赋值,可以用下面语句:strcpy(student-name,LuG.C);student-age=18;实际上,student-name就是(*student).name的缩写形式。需要指出的是结构指针是指向结构的一个指针,即结构中第一个成员的首地址,因此在使用之前应该对结构指针初始化,即分配整个结构长度的字节空间,这可用下面函数完成,仍以上例来说明如下:student=(structstring*)malloc(sizeof(structstring));sizeof(structstring)自动求取string结构的字节长度,malloc()函数定义了一个大小为结构长度的内存区域,然后将其诈地址作为结构指针返回。注意:1.结构作为一种数据类型,因此定义的结构变量或结构指针变量同样有局部变量和全程变量,视定义的位置而定。2.结构变量名不是指向该结构的地址,这与数组名的含义不同,因此若需要求结构中第一个成员的首地址应该是&[结构变量名]。3.结构的复杂形式嵌套结构嵌套结构是指在一个结构成员中可以包括其它一个结构,C允许这种嵌套。例如:下面是一个有嵌套的结构structstring{charname[8];intage;structaddraddress;}student;其中:addr为另一个结构的结构名,必须要先进行,说明,即structaddr{charcity[20];unsignedlongzipcode;chartel[14];}如果要给student结构中成员address结构中的zipcode赋值,则可写成:student.address.zipcode=200001;每个结构成员名从最外层直到最内层逐个被列出,即嵌套式结构成员的表达方式是:结构变量名.嵌套结构变量名.结构成员名其中:嵌套结构可以有很多,结构成员名为最内层结构中不是结构的成员名。结构体注意事项结构体之间不能加减乘除,但是可以相互赋值普通结构体变量和结构体指针变量作为函数传参的问题:–g1(stutctStudentstu)–g2(stutctStudent*stu)–见示例:联合体定义联合说明和联合变量定义与结构十分相似。其形式为:union联合名{数据类型成员名;数据类型成员名;...}联合变量名;联合表示几个变量公用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。下例表示说明一个联合a_bc:uniona_bc{inti;charmm;};15联合体变量在联合变量lgc中,整型量i和字符mm公用同一内存位置。当一个联合被说明时,编译程序自动地产生一个变量,其长度为联合中最大的变量长度。联合访问其成员的方法与结构相同。同样联合变量也可以定义成数组或指针,但定义为指针时,也要用-符号,此时联合访问成员可表示成:联合名-成员名16联合结构嵌套另外,联合既可以出现在结构内,它的成员也可以是结构。例如:struct{intage;char*addr;union{inti;char*ch;}x;}y[10];若要访问结构变量y[1]中联合x的成员i,可以写成:y[1].x.i;若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:*y[2].x.ch;若写成y[2].x.*ch;是错误的。结构和联合区别1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员,而结构的所有成员都存在。2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。下面举一个例了来加对深联合的理解。main(){union{/*定义一个联合*/inti;struct{/*在联合中定义一个结构*/charfirst;charsecond;}half;}number;number.i=0x4241;/*联合成员赋值*/printf(%c%c\n,number.half.first,mumber.half.second);number.half.first='a';/*联合中结构成员赋值*/number.half.second='b';printf(%x\n,number.i);}输出结果为:AB6261从上例结果可以看出:当给i赋值后,其低八位也就是first和second的值;当给first和second赋字符后,这两个字符的ASCII码也将作为i的低八位。结构与链表链表(linklist)是一些包含数据的独立数据结构(也叫节点)的数据集合。链表的每一个节点都通过链和指针链接在一起。程序通过指针来访问链表的节点。通常这些节点是动态分配的。单链表typedefstructNODE{structNODE*link;intvalue;};link5valuelink10value0link15valuehead建立一个链表[例]建立一个简单链表单链表的节点可能分布在内存的各个地方。对于一个处理链表的程序来说,各节点在物理上的位置是否相邻无关紧要,因为程序始终用链(指针)从一个节点移动到另一个节点。链表只能从开始位置遍历链表知道结束位置,不能反向遍历