前言:
此篇是针对 用结构体变量和结构体变量的指针作函数参数 方面的练习。
解题思路:
将n个学生的数据表示为结构体数组(有n个元素)。按照功能函数化的思想,分别用3个函数来实现不同的功能:
(1)用 input 函数来输入数据和求各学生平均成绩。
(2)用 max 函数来找平均成绩最高的学生。
(3)用 print 函数来输出成绩最高学生的信息。
在主函数中先后调用这3个函数,用指向结构体变量的指针作实参。最后得到结果。为简化操作,本程序只设3个学生(n=3)。
正文:
#include<stdio.h>
#define N 3 //学生数为3
struct Student { //建立结构体类型struct Student
int num; //学号
char name[20]; //姓名
float score[3]; //3门课程成绩
float aver; //平均成绩
};
int main() {
void input(struct Student stu[]); //函数声明
struct Student max(struct Student stu[]); //函数声明
void print(struct Student stud); //函数声明
struct Student stu[N],*p=stu; //定义结构体数组和指针
input(p); //调用input函数
print(max(p)); //调用print函数,以max函数的返回值作为实参
return 0;
}
void input(struct Student stu[]) { //定义input函数
int i;
printf("请输入各学生的信息:学号、姓名、三门课成绩:\n");
for(i=0; i<N; i++) {
scanf("%d %s %f %f %f",&stu[i].num,stu[i].name,
&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]); //输入数据
stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0; //求平均成绩
}
}
struct Student max(struct Student stu[]) { //定义max函数
int i,m=0; //用m存放成绩最高的学生在数组中的序号
for(i=0; i<N; i++)
if(stu[i].aver>stu[m].aver) m=i; //找出平均成绩最高的学生在数组中的学号
return stu[m]; //返回包含该生信息的结构体元素
}
void print(struct Student stud) { //定义print函数
printf("\n 成绩最高的学生是:\n");
printf("学号:%d\n 姓名:%s\n 三门课成绩:%5.1f,%5.1f,%5.1f\n平均成绩:%6.2f\n",
stud.num,stud.name,stud.score[0],stud.score[1],stud.score[2],stud.aver);
}
程序分析:
(1)
结构体类型 struct Student 中包括 num(学号)、name(姓名)、数组 score (三门课成绩)和 aver (平均成绩)。在输入数据时只输入学号、姓名和三门课成绩,未给 aver 赋值。aver 的值是在 input 函数中计算出来的。
(2)
在主函数中定义了结构体 struct Student 类型的数组 stu 和指向 struct Student 类型数据的指针变量 p ,使 p 指向 stu 数组的首元素 stu[0] 。在调用 input 函数时,用指针变量 p 作为函数实参,input 函数的形参是 struct Student 类型的数组 stu(注意形参数组 stu 和主函数中的数组 stu 都是局部变量,虽然同名,但在调用函数进行虚实结合前二者代表不同的对象,互相间没有关系)。在调用 input 函数时,将主函数中的 stu 数组的首元素的地址传给形参数组 stu,使形参数组 stu 与主函数中的 stu 数组具有相同的地址,见图9.7 .因此在 input 函数中向形参数组 stu 输入数据就等于向主函数中的 stu 数组输入数据。
在用 scanf 函数输入数据后,立即计算出该学生的平均成绩,stu[i].ever 代表序号为 i 的学生的平均成绩。请注意 for 循环体的范围。
input 函数无返回值,它的作用是给 stu 数组各元素赋予确定的值。
(3)
在主函数中调用 print 函数,实参是 max(p)。其调用过程是先调用 max 函数(以 p 为实参),得到 max(p)的值(此值是一个 struct Student 类型的数据)。然后用它调用 print 函数。
现在先分析调用 max 函数的过程:与前相同,指针变量 p 将主函数中的 stu 数组的首元素的地址传给形参数组 stu ,使形参数组 stu 与主函数中的 stu 数组具有相同的地址。在 max 函数中对形参数组的操作就是对主函数中的 stu 数组的操作。在 max 函数中,将各人平均成绩与当前的 “最高平均成绩” 比较,将平均成绩最高的学生在数组 stu 中的序号存放在变量 m 中,通过 return 语句将 stu[m] 的值返回主函数。请注意:stu[m] 是一个结构体数组的元素。max 函数的类型为 struct Student 类型。
(4)
用 max§ 的值(是结构体数组的元素)作为实参调用 print 函数。print 函数的形参 stud 是 struct Student 类型的变量(而不是 struct Student 类型的数组)。在调用时进行虚实结合,把 stu[m] 的值(是结构体元素)传递给形参 stud,这时传递的不是地址,而是结构体变量中的信息。在 print 函数中输出结构体变量中各成员的值。
(5)
以上3个函数的调用,情况各不相同:
调用 input 函数时,实参是指针变量 p,形参是结构体数组,传递的是结构体元素的地址,函数无返回值。
调用 max 函数时,实参是指针变量 p,形参是结构体数组,传递的是结构体元素的地址,函数的返回值是结构体类型数据。
调用 print 函数时,实参是结构体变量(结构体数组元素),形参是结构体变量,传递的是结构体变量中各成员的值,函数无返回值。
总结:
运行结果: