210 likes | 434 Views
单元 10 项目中结构体的应用 ---- 结构体数组的定义与访问. 学习目标: (1) 能力目标 ①能用结构体类型定义结构体数组并初始化结构体数组。 ②能用下标访问法访问结构体数组元素中的成员变量。 ③能用结构体指针变量访问结构体数组成员。 ④能将结构体数组名设计成函数参数,并进行数据传递。 (2) 知识目标 ①理解结构体数组与一般数值形数组的关系与区别。 ②理解数组的下标访问法和指针访问法在结构体数组中的应用。 ③理解指向结构体类型数组的指针与指向数值形数组的指针的关系与区别。
E N D
单元10 项目中结构体的应用----结构体数组的定义与访问 • 学习目标: (1)能力目标 ①能用结构体类型定义结构体数组并初始化结构体数组。 ②能用下标访问法访问结构体数组元素中的成员变量。 ③能用结构体指针变量访问结构体数组成员。 ④能将结构体数组名设计成函数参数,并进行数据传递。 (2)知识目标 ①理解结构体数组与一般数值形数组的关系与区别。 ②理解数组的下标访问法和指针访问法在结构体数组中的应用。 ③理解指向结构体类型数组的指针与指向数值形数组的指针的关系与区别。 ④理解结构体数组名和指向结构体数组的指针变量做函数参数的相同点与不同点。 • 能力训练: 1.用结构体数组的下标访问法和指针访问法实现对结构体数组元素成员的访问。 2.用结构体数组名和指向结构数组的指针变量做函数参数在函数中传递数据。
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 10.1.4 结构体数组的应用 结构体数据也可以成为数组元素,和前面讲过的数组不一样的是结构体数组中的元素是一个结构体类型的数据。 1.结构体数组定义与初始化 (1)结构体数组定义 由于结构体数组元素是结构体类型,所以在定义结构体数组之前必须先定义结构体类型。如:前面定义的结构体类型struct student。定义好结构体类型之后,就可以定义结构体数组了。定义结构体数组也有三种与定义结构体变量相似的方法。 ①先定义结构体类型再定义结构体数组,定义数组的方法与定义简单类型数组相似。 例如:定义好结构体类型struct student后,再定义有二个元素、数组名叫stu的数组。 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; struct student stu[2];
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 ②定义结构体类型同时,定义结构体数组。 ③匿名定义结构体数组。 structstudent { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[2]; struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[2];
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 (2)结构体数组初始化 与其他类型的数组一样,对结构体数组也可以初始化,由于有三种定义数组的方法,初始化数组也有三种不同的格式。 格式1: 例如: struct student stu[2]= { {10001,"LiMing",'M',18,89.5,"HubeiEnshi"}, {10002,"Zhang Jun",'F',17,98,"HubeiYichang"} }; 格式2: struct 结构体类型名 数组名[N]={{元素1初值},{元素2初值},……,{元素n初值}}; struct 结构体类型名 { 成员列表; }数组名[N]={{元素1初值},{元素2初值},……,{元素n初值}};
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 例如: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[2]={{10001,"LiMing",'M',18,89.5, "HubeiEnshi"}, {10002,"Zhang Jun",'F',17,98,"HubeiYichang"} }; 格式3: struct { 成员列表; }数组名[N]={{元素1初值},{元素2初值},……,{元素n初值}};
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 结构体数组初始化的其它特性与简单类型数组的特性相同,结构体数组也遵循数组三要素的原则。 上述初始化结构体数组后,系统在内存为该数组开辟了63×2=126B,开辟内存空间如图8.6所示。 图8.6 结构体数组在内存开辟空间示意图
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 2.结构体数组的访问方法 结构体数组和简单类型数组一样,访问方法也有下标访问法和指针访问法。只是要特别注意,结构体数组元素也相当于结构体变量,对它不能进行整体输入输出,输入输出的是结构体数组元素中的成员变量。 (1)下标访问法 结构体数组的下标访问法与简单类型数组的下标访问法相似,也是用循环来实现对数组元素的访问的。 【例10.6】设计有三个数组元素的学生属性数组,要求用下标访问法分别实现对学生属性的输入、输出操作。 程序代码: 1 #include <stdio.h> 2 #define N 3 3 struct student 4 { 5 int num; 6 char name[20]; 7 char sex; 8 int age; 9 float score; 10 char addr[30]; 11 };
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 12 void input(struct student stu[],int); 13 void output(struct student stu[],int); 14 void main() 15 { 16 struct student stu[N]; 17 input(stu,N); 18 output(stu,N); 19 } 20 21 void input(struct student stu[],int n) 22 { 23 int i; 24 for(i=0;i<n;i++) 25 { 26 printf("请输入第%d记录\n",i+1); 27 printf("学号:"); 28 scanf("%d",&stu[i].num); 29 printf("姓名:");
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 30 scanf("%s",stu[i].name); 31 getchar();//消除回车对输入性别的影响 32 printf("性别:"); 33 scanf("%c",&stu[i].sex); 34 printf("年龄:"); 35 scanf("%d",&stu[i].age); 36 printf("成绩:"); 37 scanf("%f",&stu[i].score); 38 printf("地址:"); 39 scanf("%s",stu[i].addr); 40 } 41 } 42 43 void output(struct student stu[],int n) 44 { 45 int i; 46 printf(" No. Name Sex Age Score Addr\n"); 47 for(i=0;i<n;i++) 48 printf("%5d%10s%5c%6d%9.1f%15s\n",stu[i].num,stu[i].name, stu[i].sex,stu[i].age,stu[i].score,stu[i].addr); 49 }
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 程序运行结果: 请输入第1记录 学号:10001 <回车> 姓名: LiMing <回车> 性别:M <回车> 年龄:18 <回车> 成绩:89.5 <回车> 地址: HubeiEnshi <回车> 请输入第2记录 学号:10002 <回车> 姓名: ZhangJun <回车> 性别:F <回车> 年龄:17 <回车> 成绩:98 <回车> 地址: HubeiYichang <回车> 请输入第3记录 学号:10003 <回车> 姓名: WangTong <回车> 性别:M <回车> 年龄:19 <回车> 成绩:87 <回车> 地址: Hubeiwuhang <回车>
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 No. Name Sex Age Score Addr 10001 Liming M 18 89.5 HubeiEnshi 10002 ZhangJun F 17 98.0 HubeiYichang 10003 WangTong M 19 87.0 Hubeiwuhan 本实例要注意的是第31行,由于输入姓名后,回车符没有送给姓名字符数组,它将保留在键盘中,接着输入性别,性别类型为字符,而回车符也是字符,如果不想办法去掉这个字符,将会影响到后面字符数据的输入,这里用getchar函数来吃掉回车符,以保证后面字符数据的正确输入。
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 (2)指针访问法 【例10.7】用指针访问法重新设计例10.6。 程序代码: 1 #include <stdio.h> 2 #define N 3 3 struct student 4 { 5 int num; 6 char name[20]; 7 char sex; 8 int age; 9 float score; 10 char addr[30]; 11 }; 12 void input(struct student *,int); 13 void output(struct student *,int); 14 void main() 15 {
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 16 struct student stu[N],*sp; 17 sp=stu; 18 input(sp,N); 19 output(sp,N); 20 } 21 22 void input(struct student *sp,int n) 23 { 24 int i=1; 25 struct student *p=sp; 26 for(;sp<p+n;sp++) 27 { 28 printf("请输入第%d记录\n",i); 29 printf("学号:"); 30 scanf("%d",&sp->num); 31 printf("姓名:"); 32 scanf("%s",sp->name); 33 getchar(); 34 printf("性别:"); 35 scanf("%c",&sp->sex); 36 printf("年龄:");
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 37 scanf("%d",&sp->age); 38 printf("成绩:"); 39 scanf("%f",&sp->score); 40 printf("地址:"); 41 scanf("%s",sp->addr); 42 i++; 43 } 44 } 45 46 void output(struct student *sp,int n) 47 { 48 struct student *p=sp; 49 printf(" No. Name Sex Age Score Addr\n"); 50 for(;sp<p+n;sp++) 51 printf("%5d%10s%5c%6d%9.1f%15s\n",sp->num,sp->name,sp->sex, sp->age,sp->score,sp->addr); 52 }
单元10 项目中结构体的应用---- 10.1.4 结构体数组的应用 程序运行结果与例10.6相同。 从上述两种实例可以看出,结构体数组名也与简单类型数组名一样也可以做实参和形参在函数之间传递地址。
单元10 项目中结构体的应用---- 10.3.4 常见错误及处理方法 10.3.4 常见错误及处理方法 常见错误1:直接使用结构体变量进行输入输出操作。 C语言规定,结构体变量不能进行直接输入输出操作,只能对结构体变量成员进行输入输出操作,结构体变量可以进行赋值操作。 常见错误2:结构体成员变量输入操作时地址引用不当。 如:scanf("%d",stu.num);或scanf("%d",sp->num);//错误 scanf("%s",&stu.name);或scanf("%s",&sp->name);//错误 结构体成员变量也是变量,它具有变量的全部属性,变量取地址操作要用到取地址符“&”;stu.name和sp->name是数组名,数组名代表数组的首地址,因此,不必再加取地址符。正确的语句应当是: scanf("%d",&stu.num);或scanf("%d",&sp->num);//正确 scanf(“%s”,stu.name);或scanf(“%s”,sp->name);//正确 常见错误3:结构体类型定义时不恰当的使用了递归定义。 C语言规定,定义结构体类型时允许嵌套定义,但不允许除自身指针类型之外的递归定义。所谓嵌套定义是指结构体成员变量是一个已定义好的其他结构体类型;所谓递归定义是用自身类型来定义结构体成员变量。 下面的递归定义是不允许的。
单元10 项目中结构体的应用---- 10.3.4 常见错误及处理方法 struct student { int num; char name[20]; float score[3]; struct student next;//变量递归定义 }; 这是因为不能准确的得到类型为变量开辟空间所设计的模型大小。即用这种结构体类型定义变量后,不知道内存为变量到底分配了多大的存储空间。如果将其换成指针类型这样的递归定义又是允许的。 struct student { int num; char name[20]; float score[3]; struct student *next;//指针变量递归定义 }; 这是因为,任何类型的指针变量内存总是为它分配4个字节的存储空间,这样就能清楚的知道用这种类型定义变量后,内存开辟空间的大小。上述类型定义变量后内存为每个就是分配40字节。
单元10 项目中结构体的应用----课后作业与思考 1.填空题: (1)下面程序的正确输出结果为。 #include <stdio.h> void main() { struct { int num; float score; }person; int num; float score; num=1; score=2; person.num=3; person.score=5; printf("%d,%f",num,score); }
单元10 项目中结构体的应用----课后作业与思考 (2)下面程序的正确输出结果为。 #include <stdio.h> struct person { int num; float score; }; void main() { struct person per,*p; per.num=1; per.score=2.5; p=&per; printf("%d,%f",p->num,p->score); }
单元10 项目中结构体的应用----课后作业与思考 2.选择题: (1)设有以下说明语句 struct student { int a; float b; }stutype;则下面的叙述不正确的是。 A.struct是结构体类型的关键字 B.struct student是用户定义的结构体类型 C.stutype是用户定义的结构体类型名 D.a和b都是结构体成员名 (2)以下程序的运行结果是。 #include <stdio.h> main() { struct date { int year,month,day; }today; printf(“%d\n”,sizeof(struct date)); } A.2 B.5 C.6 D.12
单元10 项目中结构体的应用----课后作业与思考 3.编程题: (1)自定义包含4个学生的结构体类型的数组,其成员包括学号、姓名、年龄、性别,并将其类型声明为struct student,然后用结构体数组输入输出学生的基本信息,输出要求每行显示一条学生记录。 (2)设有N名考生,每个考生的数据包括考生号、性别和成绩,编写一程序,要求用指针方法所有女生的成绩和成绩最好的男生,并输出他们的信息。