第13章 结构体的应用
description
Transcript of 第13章 结构体的应用
![Page 1: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/1.jpg)
第第 1313 章 结构体的应用章 结构体的应用13.1 了解由用户构造的数据类型13.2 结构体类型说明及结构体变量13.3 结构体数组13.4 函数之间结构体类型的数据传递13.5 利用结构体变量构成静态链表13.6 利用指针处理动态链表
![Page 2: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/2.jpg)
13.1 13.1 了解由用户构造了解由用户构造的数据类型的数据类型13.1.1 13.1.1 可以由用户构造的数据类型可以由用户构造的数据类型13.1.2 13.1.2 用用 typedeftypedef 定义类型名定义类型名
![Page 3: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/3.jpg)
13.2 结构体类型说明及结构体变量13.2.1 13.2.1 结构体类型的说明结构体类型的说明13.2.2 13.2.2 结构体变量的定义结构体变量的定义13.2.3 13.2.3 结构体变量的初始化结构体变量的初始化13.2.4 13.2.4 结构体变量中成员的访结构体变量中成员的访问问
![Page 4: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/4.jpg)
13.3 13.3 结构体数组结构体数组从例 13.1 中可以看出,利用结构体变量只能存放一名学生的信息。若要保存多名学生的信息就要使用结构体类型的数组。
13.3.1 13.3.1 结构体数组的定义结构体数组的定义定义结构体数组的方法和定义结构体变量的方法一样:可以先说明结构体类型,再用类型名定义数组;也可以在说明类型的同时定义数组。例如:
![Page 5: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/5.jpg)
struct student{ int num; char name[9]; char sex; struct date birthday; float score[3];};struct student pers[3];
![Page 6: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/6.jpg)
也可以采用以下形式:typedef struct { int num; char name[9]; char sex; struct { int year, month, day ;} birthday; float score[3];}STU;STU pers[3];
![Page 7: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/7.jpg)
以上两种形式都是先说明了类型名( struct student 或 STU ),再用类型名定义了具有 3 个元素的结构体数组 pers 。
若要直接定义结构体数组,可以采用以下两种形式:
![Page 8: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/8.jpg)
![Page 9: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/9.jpg)
结构体数组 pers 中的每个元素都是一个结构体类型,如图 13-3 所示。它们在内存中也占据着连续的存储单元。
图 13-3 数组 pers 的结构示意图
![Page 10: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/10.jpg)
13.3.2 13.3.2 结构体数组的初始化结构体数组的初始化和其他类型的数组一样,结构体数组也可以在定义的同时进行初始化。例如:
struct student pers[3]={ {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} };
![Page 11: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/11.jpg)
可以看出:所赋初值是放在一对花括号中的。为了清晰,每个元素的值又分别用一对花括号括起,中间以逗号分隔。数组 pers 赋初值后的情况如图 13-4 所示。
![Page 12: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/12.jpg)
图 13-4 数组 pers 赋初值后的示意图
![Page 13: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/13.jpg)
在定义结构体数组时,也可以不指定元素的个数,而通过初值的个数决定数组的大小。形式如下:
struct student test[ ]={ {…} , {…} ,{…} , {…} } ;
这时编译系统会根据初值的个数,判定出数组 test 有 4 个元素。
![Page 14: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/14.jpg)
13.3.3 13.3.3 结构体数组的应用结构体数组的应用结构体数组中有若干个元素,每个元素中都包含有各自的成员,应该采用什么样的形式去引用它们呢?事实上,只要把数组元素看作是带有下标的变量,就可以沿用 13.2.4 中介绍的成员引用方法:结构体变量名 . 成员名此处可理解为:结构体数组元素 . 成员名
![Page 15: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/15.jpg)
结合图 13.4 可以看出: pers[0].num
表示的是数组第 1 个元素中值为 1 的 num 成员 pers[1].sex
表示的是数组第 2 个元素中值为 F 的 sex 成员 pers[2].birthday.year
表 示 的 是 数 组 第 3 个 元 素 中 的 结 构 体birthday 中的 year 成员
![Page 16: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/16.jpg)
13.4 13.4 函数之间结构体类函数之间结构体类型的数据传递型的数据传递13.4.1 13.4.1 结构体变量的成员作实参结构体变量的成员作实参
结构体变量的成员作实参时,参数的传递情况取决于该成员本身的数据类型。如果作为实参传送的这一成员是简单变量,相应的形参应该是同类型的简单变量;如果作为实参传送的成员是数组名,对应的形参就必须是基类型相同的指针变量。
![Page 17: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/17.jpg)
例 13.4 结构体变量的成员作实参。#include <stdio.h>typedef struct{ int num; char name[9]; char sex; struct { int year,month,day ;} birthday; float score[3];}STU;
![Page 18: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/18.jpg)
void fun1(char *name) /* 形参为字符型指针 */{ printf("%9s",name); }void fun2(int y) /* 形参为整型变量 */{ printf("%5d",y); }void fun3(float *s) /* 形参为单精度型指针 */
![Page 19: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/19.jpg)
{ int i; for(i=0; i<3; i++) printf("%5.1f",s[i]); printf("\n");}main( ){ STU
std={ 1,"Zhanghua",'M',1961,10,8,76.5,78.0,82.0 };
![Page 20: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/20.jpg)
fun1(std.name);/* 相当于字符型数组名作实参 */ fun2(std.birthday.year); /* 相当于整型变量作实参 */ fun3(std.score); /* 相当于单精度型数组名作实参 */}程序的输出结果是: Zhanghua 1961 76.5 78.0 82.0
![Page 21: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/21.jpg)
13.4.2 13.4.2 结构体变量作形参结构体变量作形参结构体变量可以作为一个整体传递给相应的形参。根据“按值”传递的原则,这时传给形参的是结构体变量的值。因此,形参必须是同类型的结构体变量。系统将为形参开辟临时存储单元,用以存放结构体中各成员的值。
![Page 22: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/22.jpg)
例 13.5 结构体变量作形参。以下程序通过定义并赋初值的方式,
利用结构体变量存储了一名学生的信息,通过调用函数 show 输出其内容。
源程序如下:
![Page 23: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/23.jpg)
#include <stdio.h>typedef struct{ int num; char name[9]; char sex; struct { int year,month,day ;} birthday; float score[3];}STU;
![Page 24: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/24.jpg)
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; i<3; i++) printf("%5.1f",tt.score[i]); printf("\n");}
![Page 25: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/25.jpg)
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
![Page 26: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/26.jpg)
13.4.3 13.4.3 结构体变量的地址作实参结构体变量的地址作实参如果需要在某个函数中改变实参的值,
就一定要传地址。当实参是结构体变量的地址时,对应的形参应该是同一结构体类型的指针变量。
![Page 27: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/27.jpg)
例 13.6 在例 13.5 的基础上增加一个函数 modify ,用以将学生的各科成绩乘以一个系数,然后再调用 show 函数输出。源程序如下:#include <stdio.h>typedef struct{ int num; char name[9]; char sex; struct { int year,month,day ;} birthday; float score[3];}STU;
![Page 28: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/28.jpg)
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; i<3; i++) printf("%5.1f",tt.score[i]); printf("\n");}
![Page 29: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/29.jpg)
void modify(STU *ss,float a) /* 形参 ss 为同类型的指针 */{ int i; for(i=0; i<3; i++) ss–>score[i]*=a; /* 用指针 ss 引用结构体成员 */}
![Page 30: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/30.jpg)
main( ){ STU std={ 1,"Zhanghua",'M',1961,10,8,76.5,78.0,82.0 }; float a; printf(" 请输入系数值 : "); scanf("%f",&a); modify(&std,a); /* 结构体变量的地址作实参 */
![Page 31: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/31.jpg)
printf(" 修改后的学生数据如下: \n"); show(std);}程序运行情况如下:请输入系数值: 0.8修改后的学生数据如下:1 Zhanghua M 1961-10-8 61.2 62.4 65.6
![Page 32: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/32.jpg)
13.4.4 13.4.4 结构体数组名作实参结构体数组名作实参结构体数组名作实参,传递的是数组的首地址,相应的形参应该是同一结构体类型的指针。这一情况同 8.4.2 介绍的一维数组名作实参是类似的,区别仅在于结构体数组中的每个元素都是一个结构体类型的数据。
![Page 33: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/33.jpg)
例 13.7 计算平均分,输出成绩单。设有如下定义:typedef struct{ int num; char name[9]; float score[3]; float ave;}STD;
![Page 34: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/34.jpg)
编写函数 void fun1(STD s[ ],int n) ,用来计算 s 所指数组中每位学生 3 门课的平均分,存入相应的 ave 成员中。形参 n代表学生人数。编写函数 void fun2(STD x[ ],int n) 输出成绩单。在主函数中,利用四名学生的信息进行调试。
![Page 35: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/35.jpg)
源程序如下:void fun1(STD s[], int n){ int i,j; float sum; for(i=0; i<n; i++) /* 计算每位学生的平均分 */ { sum=0.0; for(j=0; j<3; j++) sum=sum+s[i].score[j]; s[i].ave=sum/3; }}
![Page 36: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/36.jpg)
void fun2(STD x[],int n){ int i,j; printf(" num name scor1 scor2 scor3 ave\n"); /* 输出成绩单 */ for(i=0; i<n; i++) { printf("%3d %6s ",x[i].num,x[i].name); for(j=0; j<3; j++) printf("%5.1f ",x[i].score[j]); printf("%5.1f\n",x[i].ave); }}
![Page 37: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/37.jpg)
main( ){ STD x[4]={ 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);}
![Page 38: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/38.jpg)
程序的运行结果如下: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
![Page 39: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/39.jpg)
13.5 13.5 利用结构体变量构利用结构体变量构成静态链表成静态链表13.5.1 13.5.1 构成单向链表的结点结构构成单向链表的结点结构13.5.2 13.5.2 静态链表静态链表
![Page 40: 第13章 结构体的应用](https://reader033.fdocument.pub/reader033/viewer/2022061617/56814ce9550346895db9e7d3/html5/thumbnails/40.jpg)
13.6 13.6 利用指针处理动态链利用指针处理动态链表表13.6.1 13.6.1 动态链表的概念动态链表的概念13.6.2 13.6.2 动态生成和释放结点所需动态生成和释放结点所需的函数的函数13.6.3 13.6.3 动态链表的建立和输出动态链表的建立和输出13.6.4 13.6.4 链表中结点的删除链表中结点的删除13.6.5 13.6.5 链表中结点的插入链表中结点的插入