资源预览内容
第1页 / 共40页
第2页 / 共40页
第3页 / 共40页
第4页 / 共40页
第5页 / 共40页
第6页 / 共40页
第7页 / 共40页
第8页 / 共40页
第9页 / 共40页
第10页 / 共40页
亲,该文档总共40页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第13章 结构体的应用,13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组 13.4 函数之间结构体类型的数据传递 13.5 利用结构体变量构成静态链表 13.6 利用指针处理动态链表,13.1 了解由用户构造的数据类型,13.1.1 可以由用户构造的数据类型 13.1.2 用typedef定义类型名,13.2 结构体类型说明及结构体变量,13.2.1 结构体类型的说明 13.2.2 结构体变量的定义 13.2.3 结构体变量的初始化 13.2.4 结构体变量中成员的访问,13.3 结构体数组,从例13.1中可以看出,利用结构体变量只能存放一名学生的信息。若要保存多名学生的信息就要使用结构体类型的数组。 13.3.1 结构体数组的定义 定义结构体数组的方法和定义结构体变量的方法一样:可以先说明结构体类型,再用类型名定义数组;也可以在说明类型的同时定义数组。例如:,struct student int num; char name9; char sex; struct date birthday; float score3; ; struct student pers3;,也可以采用以下形式: typedef struct int num; char name9; char sex; struct int year, month, day ; birthday; float score3; STU; STU pers3;,以上两种形式都是先说明了类型名(struct student或STU),再用类型名定义了具有3个元素的结构体数组pers。 若要直接定义结构体数组,可以采用以下两种形式:,结构体数组pers中的每个元素都是一个结构体类型,如图13-3所示。它们在内存中也占据着连续的存储单元。,图13-3 数组pers 的结构示意图,13.3.2 结构体数组的初始化 和其他类型的数组一样,结构体数组也可以在定义的同时进行初始化。例如: struct student pers3= 1,“Zhanghua“,M,1961,10,8,76.5,78.0,82.0, 2,“Wangwei“,F,1960,12,20,70.0,85.5,76.0, 3,“Liming“, M,1961,3,16,80.0,84.5,91.0 ;,可以看出:所赋初值是放在一对花括号中的。为了清晰,每个元素的值又分别用一对花括号括起,中间以逗号分隔。数组pers赋初值后的情况如图13-4所示。,图13-4 数组pers赋初值后的示意图,在定义结构体数组时,也可以不指定元素的个数,而通过初值的个数决定数组的大小。形式如下: struct student test = , ; 这时编译系统会根据初值的个数,判定出数组test有4个元素。,13.3.3 结构体数组的应用 结构体数组中有若干个元素,每个元素中都包含有各自的成员,应该采用什么样的形式去引用它们呢?事实上,只要把数组元素看作是带有下标的变量,就可以沿用13.2.4中介绍的成员引用方法: 结构体变量名.成员名 此处可理解为: 结构体数组元素.成员名,结合图13.4可以看出: pers0.num 表示的是数组第1个元素中值为1的num成员 pers1.sex 表示的是数组第2个元素中值为F的sex成员 pers2.birthday.year 表示的是数组第3个元素中的结构体birthday中的year成员,13.4 函数之间结构体类型的数据传递,13.4.1 结构体变量的成员作实参 结构体变量的成员作实参时,参数的传递情况取决于该成员本身的数据类型。如果作为实参传送的这一成员是简单变量,相应的形参应该是同类型的简单变量;如果作为实参传送的成员是数组名,对应的形参就必须是基类型相同的指针变量。,例13.4 结构体变量的成员作实参。 #include typedef struct int num; char name9; char sex; struct int year,month,day ; birthday; float score3; STU;,void fun1(char *name) /* 形参为字符型指针 */ printf(“%9s“,name); void fun2(int y) /* 形参为整型变量 */ printf(“%5d“,y); void fun3(float *s) /* 形参为单精度型指针 */, int i; for(i=0; i3; i+) printf(“%5.1f“,si); printf(“n“); main( ) STU std= 1,“Zhanghua“,M,1961,10,8,76.5,78.0,82.0 ;,fun1(std.name); /* 相当于字符型数组名作实参 */ fun2(std.birthday.year); /* 相当于整型变量作实参 */ fun3(std.score); /* 相当于单精度型数组名作实参 */ 程序的输出结果是: Zhanghua 1961 76.5 78.0 82.0,13.4.2 结构体变量作形参 结构体变量可以作为一个整体传递给相应的形参。根据“按值”传递的原则,这时传给形参的是结构体变量的值。因此,形参必须是同类型的结构体变量。系统将为形参开辟临时存储单元,用以存放结构体中各成员的值。,例13.5 结构体变量作形参。 以下程序通过定义并赋初值的方式,利用结构体变量存储了一名学生的信息,通过调用函数show输出其内容。 源程序如下:,#include typedef struct int num; char name9; char sex; struct int year,month,day ; birthday; float score3; STU;,void show(STU tt) /* 形参是同类型的结构体变量 */ int i; printf(“%d %s %c %d%d%d“, tt.num,tt.name,tt.sex, tt.birthday.year,tt.birthday.month,tt.birthday.day); for(i=0; i3; i+) printf(“%5.1f“,tt.scorei); printf(“n“); ,main( ) STU std= 1,“Zhanghua“,M,1961,10,8,76.5,78.0,82.0 ; show(std); /* 结构体变量作实参 */ 程序的运行结果如下: 1 Zhanghua M 1961-10-8 76.5 78.0 82.0,13.4.3 结构体变量的地址作实参 如果需要在某个函数中改变实参的值,就一定要传地址。当实参是结构体变量的地址时,对应的形参应该是同一结构体类型的指针变量。,例13.6 在例13.5的基础上增加一个函数modify,用以将学生的各科成绩乘以一个系数,然后再调用show函数输出。 源程序如下: #include typedef struct int num; char name9; char sex; struct int year,month,day ; birthday; float score3; STU;,void show(STU tt) int i; printf(“%d %s %c %d%d%d“, tt.num,tt.name,tt.sex, tt.birthday.year,tt.birthday.month,tt.birthday.day); for(i=0; i3; i+) printf(“%5.1f“,tt.scorei); printf(“n“); ,void modify(STU *ss,float a) /* 形参ss为同类型的指针 */ int i; for(i=0; iscorei*=a; /* 用指针ss引用结构体成员 */ ,main( ) STU std= 1,“Zhanghua“,M,1961,10,8,76.5,78.0,82.0 ; float a; printf(“请输入系数值: “); scanf(“%f“, /* 结构体变量的地址作实参 */,printf(“修改后的学生数据如下:n“); show(std); 程序运行情况如下: 请输入系数值:0.8 修改后的学生数据如下: 1 Zhanghua M 1961-10-8 61.2 62.4 65.6,13.4.4 结构体数组名作实参 结构体数组名作实参,传递的是数组的首地址,相应的形参应该是同一结构体类型的指针。这一情况同8.4.2介绍的一维数组名作实参是类似的,区别仅在于结构体数组中的每个元素都是一个结构体类型的数据。,例13.7 计算平均分,输出成绩单。设有如下定义: typedef struct int num; char name9; float score3; float ave; STD;,编写函数 void fun1(STD s ,int n),用来计算s所指数组中每位学生3门课的平均分,存入相应的ave成员中。形参n代表学生人数。 编写函数 void fun2(STD x ,int n) 输出成绩单。 在主函数中,利用四名学生的信息进行调试。,源程序如下: void fun1(STD s, int n) int i,j; float sum; for(i=0; in; i+) /* 计算每位学生的平均分 */ sum=0.0; for(j=0; j3; j+) sum=sum+si.scorej; si.ave=sum/3; ,void fun2(STD x,int n) int i,j; printf(“ num name scor1 scor2 scor3 aven“); /* 输出成绩单 */ for(i=0; in; i+) printf(“%3d %6s “,xi.num,xi.name); for(j=0; j3; j+) printf(“%5.1f “,xi.scorej); printf(“%5.1fn“,xi.ave); ,main( ) STD x4= 1,“Limi“,60,67,76,0.0, 2,“Mali“,73,81,69,0.0, 3,“Qiyin“,86,75,82,0.0, 4,“Jake“,66,85,72,0.0; /* 初始化时存放平均分的成员值为0.0 */ fun1(x,4); fun2(x,4); ,程序的运行结果如下: num name scor1 scor2 scor3 ave 1 Limi 60.0 67.0 76.0 67.7 2 Mali 73.0 81.0 69.0 74.3 3 Qiyin 86.0 75.0 82.0 81.0 4 Jake 66.0 85.0 72.0 74.3,13.5 利用结构体变量构成静态链表,13.5.1 构成单向链表的结点结构 13.5.2 静态链表,13.6 利用指针处理动态链表,13.6.1 动态链表的概念 13.6.2 动态生成和释放结点所需的函数 13.6.3 动态链表的建立和输出 13.6.4 链表中结点的删除 13.6.5 链表中结点的插入,
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号