c语言学习c语言课件第09章.ppt
第9章结构体与共用体本章学习目标本章学习目标q掌握结构体类型的定义。掌握结构体类型的定义。q熟练掌握结构体变量的引用和初始化。熟练掌握结构体变量的引用和初始化。q掌握结构体数组的使用。掌握结构体数组的使用。q熟练掌握指向结构体类型的指针的使用。熟练掌握指向结构体类型的指针的使用。q掌握共用体数据类型的定义和引用。掌握共用体数据类型的定义和引用。q了解枚举类型和用了解枚举类型和用TYPEDEF定义类型。定义类型。Return9.1 结构体类型与结构体变量的定义 9.2 结构体变量的引用与初始化 9.3 结构体数组 9.4 指向结构体类型数据的指针 9.5 共用体 9.6 枚举类型 9.7 用typedef定义类型 9.8 结构体应用举例 9.1 结构体类型与结构体变量的定义 9.1.1 结构体类型的定义结构体类型的定义 在生活中我们通常会在住宿表上登记姓名、性别、身份证号码等项目;在通讯地址表中记录姓名、邮编、邮箱地址、电话号码、E-mail等项目。这些表中集合了各种类型的数据,无法用前面学过的任一种简单数据类型完全描述,因此C引入一种能集中不同数据类型于一体的数据类型结构体类型。姓名(字符串)性别(字符)职业(字符串)年龄(整型)身份证号码(长整型或字符串)住宿表可由下面的项目构成:下面让我们分析一下住宿表、成绩表、通讯地址等数据的特点。成绩表可由下面的项目构成:班级(字符串)学号(长整型)姓名(字符串)操作系统(实型)数据结构(实型)计算机网络(实型)姓名(字符串)工作单位(字符串)家庭住址(字符串)邮编(长整型)电话号码(字符串或长整型)通讯地址表可由下面的项目构成:E-mail(字符串)显然,这些登记表中包含多种不同数据类型的数据项,用简单类型的变量无法描述清楚。但可用C语言提供的结构体类型描述如下:/*住宿表结构*/struct accommodchar name20;/*姓名*/char sex;/*性别*/char job40;/*职业*/int age;/*年龄*/long number;/*身份证号码*/;/*成绩表结构*/struct score char grade20;/*班级*/long number;/*学号*/char name20;/*姓名*/float os;/*操作系统*/float datastru;/*数据结构*/float compnet;/*计算机网络*/;/*通讯地址表结构*/struct addr char name20;char department30;/*部门*/char address30;/*住址*/long box;/*邮编*/long phone;/*电话号码*/char email30;/*Email*/;像这些对不同登记表的数据结构的描述类型称为结构体类型 C语言对结构体类型定义的一般形式如下:struct struct 结构体名结构体名 成员项表列成员项表列 ;/*此行分号不能少!*/有了结构体类型,我们就可以定义结构体类型变量,对不同变量的各成员进行引用。9.1.2 结构体类型变量的定义结构体类型变量的定义 结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对问题事先自行定义,所以结构体类型变量的定义形式就增加了灵活性,共计有3种形式,分别介绍如下:1.1.先定义结构体类型,再定义结构体类型变量:先定义结构体类型,再定义结构体类型变量:struct stu /*定义学生结构体类型*/char name20;/*学生姓名*/char sex;/*性别*/long num;/*学号*/float score3;/*三科考试成绩*/;struct stu student1,student2;/*定义结构体类型变量*/用此结构体类型,可以定义更多的该结构体类型变量。2.2.定义结构体类型同时定义结构体类型变量:定义结构体类型同时定义结构体类型变量:struct data int day;int month;int year;time1,time2;也可以再定义如下变量:struct data time3,time4;用此结构体类型,同样可以定义更多的该结构体类型变量。3.3.直接定义结构体类型变量:直接定义结构体类型变量:struct char name20;/*学生姓名*/char sex;/*性别*/long num;/*学号*/float score3;/*三科考试成绩*/person1,person2;/*定义该结构体类型变量*/注意:注意:该定义方法由于无法记录该结构体类型,所以除直接定义外,不能再定义该结构体类型变量。关于结构体类型,有几点要说明:(1)类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。(2)数据类型相同的数据项,既可逐个、逐行分别定义,也可合并成一行定义。例如,上面的日期结构类型,也可改为如下形式:struct date int year,month,day;(3)结构体中的成员,既可以是基本数据类型,也允许是另一个已经定义的结构类型。如:struct data int day;int month;int year;struct stu /*定义学生结构体类型*/char name20;/*学生姓名*/char sex;/*性别*/long num;/*学号*/struct data birthday;/*birthday是struct data类型*/float score3;/*三科考试成绩*/student1,student2;在stu结构中的birthday成员又是一个结构体(struct data)类型的变量。(4)成员名可以与程序中的变量名相同,但二者不代表同一对象。9.2 结构体变量的引用与初始化 9.2.1 9.2.1 结构体类型变量的引用结构体类型变量的引用 引用结构体类型变量的一般形式为:引用结构体类型变量的一般形式为:结构体类型变量名结构体类型变量名.成员名成员名其中其中“.”“.”是是成员成员(分量分量)运算符运算符,它在所有运算符中优先级最高。,它在所有运算符中优先级最高。说明:说明:(1)(1)结构体类型变量的各成员与相应的简单类型变量一样可以进行结构体类型变量的各成员与相应的简单类型变量一样可以进行各种运算,例如:各种运算,例如:student2.score1=student1.score1;student2.score1=student1.score1;sum=stud1.score0+stud1.score1+stud1.score2;sum=stud1.score0+stud1.score1+stud1.score2;(2)(2)如果成员本身又属一个结构体类型,则要用若干成员运算符,如果成员本身又属一个结构体类型,则要用若干成员运算符,一级一级地找到最低的一级成员。一级一级地找到最低的一级成员。只能对最低级的成员进行赋只能对最低级的成员进行赋值或存取以及运算值或存取以及运算。例如:。例如:student1.birthday.day=01student1.birthday.day=01;student1.birthday.month=10student1.birthday.month=10;student.birthday.year=2004student.birthday.year=2004;(3)可以引用结构体类型变量成员的地址,也可以引用结构体变量的地址。例如:scanf(%f,&student.scorei)9.2.2 结构体类型变量的初始化结构体类型变量的初始化 和其他类型变量一样,对结构体变量可以在定义时指定初始值,但结构体类型变量汇集了各类不同数据类型的成员,所以结构体类型变量的初始化就略显复杂。例如:struct stu /*定义学生结构体类型*/char name20;/*学生姓名*/char sex;/*性别*/long num;/*学号*/float score3;/*三科考试成绩*/;struct stu student=liping,f,970541,98.5,97.4,95;当然我们也可以通过C提供的输入输出函数完成对结构体类型变量成员的赋值。由于结构体类型变量成员的数据类型通常是不一样的,所以一般是将结构体类型变量成员以字符串的形式输入,利用C的类型转换函数将其转换为所需类型。类型转换的函数有:int atoi(char*str);/*转换str所指向的字符串为整型。*/double atof(char*str);/*转换str所指向的字符串为实型。*/long atol(char*str);/*转换str所指向的字符串为长整型。*/使用上述函数,要包含头文件stdlib.h。例如,对上述的结构体类型变量student各成员赋值可以采用以下方法:char temp20;gets(student.name);/*输入姓名*/student.sex=getchar();/*输入性别*/gets(temp);/*输入学号*/student.num=atol(temp);/*转换为长整型*/for(i=0;i3;i+)/*输入三科成绩*/gets(temp);student.scorei=atoi(temp);/*转换为整型*/9.3 结构体数组 结构体数组与前面介绍过的基本数据类型数组的不同之处是每个数组元素都是一个结构体类型的数据,都包括多个成员数据项。9.3.1 9.3.1 结构体数组的定义结构体数组的定义 和定义结构体变量的方法相仿,只需说明其为数组即可。如:struct stu /*定义学生结构体类型*/char name20;/*学生姓名*/char sex;/*性别*/long num;/*学号*/float score3;/*三科考试成绩*/;struct stu stud3;/*定义结构体类型数组stud*/9.3.2 9.3.2 结构体数组的初始化结构体数组的初始化 与其他类型一样,对结构体数组可以初始化。如:struct stu char name20;char sex;long num;float score3;struct stu stud3=liping,m,9901,78.4,68.5,99.4,weifeng,f,9902,67.4,88.5,90.0,xiaoling,m,9903,87.5,97.5,80.0;结构数组名结构数组名nn初值表初值表11,初值表初值表22,.,初值表初值表nn;9.3.3 结构体数组应用举例结构体数组应用举例【例【例9-19-1】建立一个有4个人的电子通信录,并输出通信录的内容。【思路导航】【思路导航】设通信录的每一条记录都包括姓名、性别、出生年月、通信地址和联系电话几项,而在这几项中,出生年月又包括年份、月份和日期,通信地址又包括邮编和家庭地址两项,我们把这些联系较为紧密的内容又用单独的结构表示。对于4个人的记录可以定义一个包含4个元素的结构体数组。/*exam9_1*/*exam9_1*/#include stdio.hstruct addr /*通信地址结构定义*/char postcode10;/*邮编*/char addr40;/*家庭住址*/;struct birth /*出生年月结构定义*/int year;int month;int day;struct friend /*电子通信录结构定义*/int number;char name20;char sex;struct birth birthday;struct addr address;char telephone13;friends4;int main(void)int i;/*以下是输入信息*/for(i=0;i4;i+)friendsi.number=i+1;printf(tenter NO.%d s data:n,i+1);printf(tenter name:);scanf(%s,friendsi.name);getchar();/*清除键盘缓冲区对输入的影响*/printf(ntenter sex(m/f):);scanf(%c,&friendsi.sex);printf(ntenter birthday:);printf(nttyear:);scanf(%d,&friendsi.birthday.year);printf(nttmonth:);scanf(%d,&friendsi.birthday.month);printf(nttday:);scanf(%d,&friendsi.birthday.day);printf(ntpostcode:);scanf(%s,friendsi.address.postcode);printf(ntaddress:);scanf(%s,friendsi.address.addr);printf(ntphone:);scanf(%s,friendsi.telephone);/*以下是输出信息*/for(i=0;ipostcode=”510070”;p-addr=”guangzhou”;结构体变量在内存中的起始地址称为结构体变量的指针。下面通过一个简单例子来说明指向结构体变量的指针的应用。【例【例9-29-2】先从键盘给一个结构体类型变量的各成员赋值,然后在屏幕输出。/*exam9_2*/*exam9_2*/#includestdio.h#includestdlib.h /*使用malloc()需要*/struct addr char name10;char department10;/*部门*/char address20;/*住址*/char code10;/*邮编*/char phone12;/*电话号码*/char email20;/*Email*/;int main(void)/*定义main()函数*/struct addr*person;/*定义结构体类型指针变量*/person=malloc(sizeof(struct addr);/*为指针变量分配安全的地址*/printf(enter name,department,address,postcode,phone,Email:n);gets(person-name);gets(person-department);gets(person-address);gets(person-code);gets(person-phone);gets(person-email);/*以下打印输出各成员项的值*/printf(nname:%sn,person-name);printf(department:%sn,person-department);printf(address:%sn,person-address);printf(postcode:%sn,person-code);printf(phone:%sn,person-phone);printf(Email:%sn,person-email);return 0;通过指向结构变量的指针来访问结构变量的成员,与直接使用结构变量的效果是一样的,只是使用的成员运算符不同,前者为“-”,后者为“.”。如果指针变量pointer已指向结构变量var,则以下三种形式是等价的:(1)var.成员(2)pointer-成员 /*“-”称为指向运算符*/(3)(*pointer).成员 /*括号不能省!*/演示9.4.2 指向结构体数组的指针指向结构体数组的指针 定义结构体类型的指针,既可以指向结构体变量,也可以指向结构体数组。例如,可以在例9-2中定义的结构体类型基础上再定义结构体数组及指向结构体类型的指针如下:struct addr char name10;char department10;/*部门*/char address20;/*住址*/char code;/*邮编*/char phone;/*电话号码*/char email20;/*Email*/;struct addr person4,*p;/*定义结构体数组person及指向结构体类型的指针p*/p=person;语句“p=person;”使指针p指向了结构体数组person。对数组元素的引用可采用三种方法。1)地址法person+i和p+i均表示数组第i个元素的地址,数组元素各成员的引用形式为:(person+i)-name、(person+i)-department和(p+i)-name、(p+i)-department等。person+i和 p+i与&personi意义相同。2)指针法若p指向数组的某一个元素,则p+就指向其后续元素。3)指针的数组表示法若p=person,我们说指针p指向数组person,pi表示数组的第i个元素,其效果与personi等同。对数组成员的引用描述为:pi.name、pi.department等。【例【例9-39-3】指向结构体数组的指针变量的使用。/*exam9_3*/*exam9_3*/#include stdio.hstruct addr char name10;char department10;/*部门*/char address20;/*住址*/char code10;/*邮编*/char phone12;/*电话号码*/char email20;/*Email*/;int main(void)int i;struct addr*p,person4=liying,信息学院,文明路5号东3栋302,524001,3385201,wangping,文法学院,文明路5号东5栋402,524001,3385212,libo,航海学院,解放路34号西4栋205,524011,2382424,xuyan,工程学院,海滨路43号2号楼302,524005,2382465,;p=person;/*将数组的首地址赋值给指针p,p 指向了一维数组person*/for(i=0;iname);printf(部门:%sn,(p+i)-department);printf(地址:%sn,(p+i)-address);printf(邮编:%sn,(p+i)-code);printf(电话:%sn,(p+i)-phone);printf(Email:%sn,(p+i)-email);return 0;演示9.5 共用体 共用体类型也是用来描述类型不同的数据,但与结构体类型不同,共用体数据成员存储时采用覆盖技术,各数据成员共享(或部分共享)同一块存储空间。在结构体中增加共用体类型成员,可使结构体中产生动态成员。共用体类型在有的书中亦称为联合体。9.5.1 9.5.1 共用体类型的定义共用体类型的定义共用体的定义用关键字union标识,形式为:union union 共用体名共用体名 成员表列成员表列 ;例如:union data int i;char ch;float f;;共用体数据类型union data包含一个整型成员、一个字符成员和一个单精度浮点数类型成员。共用体数据类型与结构体在形式上非常相似,但其表示的含义及存储是完全不同的。结构体中的成员有各自的存储空间,结构体变量所占的内存长度等于各成员的长度之和,而共用体的各成员是共用一段内存空间,因此共用体变量所占的内存长度等于最长成员的长度,如图9-2所示。4字节1字节变量i变量f变量ch结构体 ich共用体f图9-2共用体类型与结构体类型占用存储空间的比较2字节9.5.2 共用体变量的定义共用体变量的定义 共用体变量的定义与结构体变量的定义类似,也有三种方法:1.先定义共用体类型,再定义共用体类型变量。如:union data int i;char ch;float f;;union data un1,un2,un3;这里先定义了共用体类型data,然后定义了三个共用体变量un1、un2、un3。2.定义共用体类型同时定义共用体类型变量。如:union data int i;char ch;float f;un1,un2,un3;3.直接定义共用体类型变量。如:union int i;char ch;float f;un1,un2,un3;提倡使用第一种方法。9.5.3 9.5.3 共用体变量的引用共用体变量的引用共用变量体的引用与结构体变量一样,也只能逐个引用共用体变量的成员。例如,访问共用体变量un1各成员的格式为:un1.i、un1.ch、un1.f。说明:说明:(1)共用体变量中,可以包含若干个成员及若干种类型,但共用体成员不能同时使用。在每一时刻,只有一个成员及一种类型起作用,不能同时引用多个成员及多种类型。(2)共用体数据成员存储时采用覆盖技术,实现共用体变量各成员的内存共享,所以在某一时刻,存放的和起作用的是最后一次存入的成员值。例如,执行un1.i=1,un1.ch=c,un1.f=3.14后,un1.f才是有效的成员。(3)由于所有成员共享同一内存空间,故共用变量与其各成员的地址相同。例如,un1un1.iun1.chun1.f。(4)不能对共用变量进行初始化(注意:结构变量可以);也不能将共用变量作为函数参数,以及使函数返回一个共用数据,但可以使用指向共用变量的指针。(5)共用类型可以出现在结构类型定义中,反之亦然。【例9-5】设有若干人员的数据,其中有学生和教师,教师的数据中包括编号、姓名、职业、职务,学生的数据中包括编号、姓名、职业、班级。现要求把这些数据放在同表格中,如图9-3。【思路导航】【思路导航】这些数据中,编号、姓名、职业是三个固定字段,第四个字段是动态字段,可能是职务(字符型),也可能是班级(整型),两个中选一个,故用共用体类型描述。假设考虑三个人员的数据,用结构体数组来描述。/*exam9_5*/*exam9_5*/#include stdio.h#include string.hunion cf /*定义共用体cf*/int classes;/*班级*/char position10;/*职务*/;struct int num;/*编号*/char name10;/*姓名*/char job4;/*职业*/union cf categroy;/*该成员为共用体成员,存放班级或职务*/person3;/*定义结构体数组*/int main(void)int i;for(i=0;i3;i+)printf(输入第输入第%d个人员的资料:个人员的资料:n,i+1);scanf(%d%s%s,&personi.num,personi.name,personi.job);if(!strcmp(personi.job,学生学生)scanf(%d,&personi.categroy.classes);else scanf(%s,personi.categroy.position);for(i=0;iSun、Sat最大。(4)枚举元素的值也是可以人为改变的:在定义时由程序指定。例如,如果enum weekdays Sun=,Mon,Tue,Wed,Thu,Fri,Sat;则Sun=,Mon=,从Tue=2开始,依次增。【例【例9-59-5】从键盘输入一整数,显示与之对应的星期值。/*exam9_5*/#include stdio.hint main(void)enum weekdays Mon=1,Tue,Wed,Thu,Fri,Sat,sun workday;int i;printf(请输入一个整数:请输入一个整数:n);scanf(%d,&i);workday=(enum weekdays)i;/*将将i强制转换为枚举类型强制转换为枚举类型*/switch(workday)case Sun:printf(Sundayn);break;case Mon:printf(Mondayn);break;case Tue:printf(Tuesdayn);break;case Wed:printf(Wednesdayn);break;case Thu:printf(Thursdayn);break;case Fri:printf(Fridayn);break;case Sat:printf(Saturdayn);break;default:printf(Input errorn);return 0;演示9.7 用typedef定义类型 在C语言中除可直接使用提供的标准类型和自定义的类型(结构体、共用体、枚举等)外,也可使用typedef定义已有类型的别名。该别名与标准类型名一样,可用来定义相应的变量。typedef类型定义的含义是给某个已有的数据类型重新命名,即允许给指定的数据类型定义一个新的名字(原名称仍然可用),其形式为:typedef typedef 类型名类型名 新名称新名称其中,“typedef”类型定义的语句的关键字;“类型名”是系统提供的标准类型名,或者是一个已定义的类型名;“新名称”为用户定义的与类型名等价的一个别名。例如:typedef float REAL;/*给实型float定义一个别名REAL*/REAL a,b;/*定义实型变量a、b*/typedef struct date int year,month,day;DATE;/*为结构体定义一个别名DATE*/DATE birthday;/*定义一个结构体类型的变量birthday*/typedef int NUM10;/*定义NUM 为包含10个元素的数组类型*/NUM a,b;/*定义了两个包含有10个元素的一维数组a、b*/相当于int a10,b10;说明:(1)用typedef只是给已有类型增加个别名,并不能创造个新的类型。就如同人一样,除学名外,可以再取一个小名(或雅号),但并不能创造出另一个人来。(2)typedef与#define有相似之处,但二者是不同的:前者是由编译器在编译时处理的;后者是由编译预处理器在编译预处理时处理的,而且只能作简单的字符串替换。(3)定义的别名一般使用大写字母,以便与系统的标准类型标识符相区别。(4)当不同源文件中用到同一数据类型(尤其是像数组、指针、结构体、共用体等数据类型)时,常用typedef声明一些数据类型,把它们单独放在一个文件中,然后在需要用到它们的文件中用#include命令把它们包含进来。(5)使用typedef有利于程序的通用与移植。例如有系统int 型为2个字节,而有的为4个字节,若要进行程序移植,一定会出现问题,假如在甲机器上int 为2 个字节,在程序中这样定义:“typedef int INTEGER;”,程序中就可用INTEGER定义变量。此时若想移植到乙机器上,而其int为4个字节,那么只需将“typedef int INTEGER;”改 动 为:“typedef long INTEGER;”就可以了,其它地方不用修改。9.8 结构体应用举例【例【例9-79-7】以下是4个学生的成绩登记表,除姓名、学号外,还有三科成绩,编程实现对表格的计算:求出各人的平均分以及各科的平均分,并按各人平均成绩由高分到低分输出。Name number English Physics Mathema AverageLiping 001 78 98 76Wangling 002 66 90 86Jiangbo 003 89 70 76Yangming 004 90 100 67题目要求的问题多,采用模块化编程方式,将问题进行分解如下:1)结构体类型数组的输入。2)求解各学生的三科平均成绩。3)按学生的平均成绩排序。4)按表格要求输出。5)求解各学生单科平均成绩并输出。6)定义main()函数,调用各子程序。第一步,根据具体情况定义结构体类型。struct stuchar name20;/*姓名*/long number;/*学号*/float score4;/*数组依此存放English、Mathema、Physics,及Average*/;由于有多个子模块需要使用该结构体类型,所以将其定义为外部的结构体类型,放在程序的最前面。第二步,定义结构体类型数组的输入模块。第二步,定义结构体类型数组的输入模块。/*/*输入结构体类型数组输入结构体类型数组arrarr的的n n个元素个元素*/*/void input(struct stu arr,int n)void input(struct stu arr,int n)int i,j;int i,j;char temp30;char temp30;for(i=0;in;i+)for(i=0;in;i+)/*/*打印提示信息打印提示信息*/*/printf(ninputname,number,English,mathema,physicn);printf(ninputname,number,English,mathema,physicn);gets(arri.name);/*gets(arri.name);/*输入姓名输入姓名*/*/gets(temp);/*gets(temp);/*输入学号输入学号*/*/arri.number=atol(temp);arri.number=atol(temp);for(j=0;j3;j+)for(j=0;j3;j+)gets(temp);/*gets(temp);/*输入三科成绩输入三科成绩*/*/arri.scorej=atof(temp);arri.scorej=atof(temp);第三步,求解各学生的三科平均成绩。结构体数组中第i个元素arri的成员score的前三个元素为已知,第四个Average需计算得到。void aver(struct stu arr,int n)int i,j;for(i=0;in;i+)/*n个学生*/arri.score3=0;for(j=0;j3;j+)arri.score3=arri.score3+arri.scorej;/*求和*/arri.score3=arri.score3/3;/*平均成绩*/第四步,按平均成绩由大到小排序,排序算法采用冒泡法。void order(struct stu arr,int n)struct stu temp;int i,j;for(i=0;in-1;i+)for(j=0;jn-1-i;j+)if(arrj.score3arrj+1.score3)temp=arrj;/*结构体类型变量不允许以整体输入或输出,但允许相互赋值*/arrj=arrj+1;/*进行交换*/arrj+1=temp;第五步,按表格要求输出。/*以表格形式输出有n个元素的结构体类型数组各成员*/void output(struct stu arr,int n)int i,j;printf(*TABLE*n);/*打印表头*/printf(-n);/*输出一条水平线*/printf(|%10s|%8s|%7s|%7s|%7s|%7s|n,Name,Number,English,Mathema,physics,average);/*输出效果为:|Name|Number|English|Mathema|Physics|Average|*/printf(-n);for(i=0;in;i+)printf(|%10s|%8ld|,arri.name,arri.number);/*输出姓名、学号*/for(j=0;j4;j+)printf(%7.2f|,arri.scorej);/*输出三科成绩及三科的平均*/printf(n);printf(-n);(续)第六步,求解组内学生单科平均成绩并输出。在输出表格的最后一行,输出单科平均成绩及总平均。void out_row(struct stu arr,int n)/*对n个元素的结构体类型数组求单项平均*/float row4=0,0,0,0;/*定义存放单项平均的一维数组*/int i,j;for(i=0;i4;i+)for(j=0;jn;j+)rowi=rowi+arrj.scorei;/*计算单项总和*/rowi=rowi/n;/*计算单项平均*/printf(|%19c|,);/*按表格形式输出*/for(i=0;i4;i+)printf(%7.2f|,rowi);printf(n-n);(续)第七步,定义main()函数,把上面各函数组装起来,列出完整的程序清单。/*exam9_6*/*exam9_6*/#include stdlib.h#include stdio.hstruct stuchar name20;long number;float score4;int main(void)void input(struct stu arr,int n);/*函数声明*/void aver(struct stu arr,int n);void order(struct stu arr,int n);void output(struct stu arr,int n);void out_row(struct stu arr,int n);(续)struct stu stud4;/*定义结构体数组*/input(stud,4);/*依次调用自定义函数*/aver(stud,4);order(stud,4);output(stud,4);out_row(stud,4);return 0;(略)演示 说明:程序中要谨慎处理以数组名作函数的参数。由于数组名作为数组的首地址,在形参和实参结合时,传递给函数的就是数组的首地址。形参数组的大小最好不定义,以便与调用函数时的实参数组保持一致。在定义的结构体内,成员score3用于存放计算的平均成绩,也是排序的依据。数组元素是结构体数据,无法直接进行相互比较,而只能用数组元素的成员score3进行比较。在交换的时候,要将数组元素以一个整体(包括姓名、学号、三科成绩及平均成绩)进行交换。作业与实验作业:习题九?上机操作:实验九Return