收藏 分享(赏)

第9章 结构体及其应用.ppt

上传人:j35w19 文档编号:8221146 上传时间:2019-06-15 格式:PPT 页数:87 大小:604.50KB
下载 相关 举报
第9章 结构体及其应用.ppt_第1页
第1页 / 共87页
第9章 结构体及其应用.ppt_第2页
第2页 / 共87页
第9章 结构体及其应用.ppt_第3页
第3页 / 共87页
第9章 结构体及其应用.ppt_第4页
第4页 / 共87页
第9章 结构体及其应用.ppt_第5页
第5页 / 共87页
点击查看更多>>
资源描述

1、第9章 结构体及其应用,第9章 结构体及其应用,学习目标 掌握构造类型结构体类型及其使用。学习内容 结构体类型及其定义,结构体变量的定义及使用,结构体数组的使用,结构体指针的使用,链表及其基本操作。,下一页,返 回,第9章 结构体及其应用,9.1 一个程序实例 9.2 结构体类型的使用 9.3 链表 9.4 结构体应用实例 9.5 本章小结 9.6 实训,上一页,返 回,9.1 一个程序实例,【例9-1】一个学生的信息包括学号、姓名、平时成绩、期末成绩和总评成绩,其中总评成绩的计算公式为: 总评成绩=平时成绩30%+期末成绩70% 根据给定的平时成绩和期末成绩计算总评成绩,并输出学生的信息。

2、【编程思路】 本实例中学生的信息包含5个数据项,这些数据项具有内在的联系(同属于一个学生),然而数据类型却不尽相同。那么,能否将不同类型的数据项组合成一个有机的整体,以方便引用呢?C语言可以做到。C语言允许编程者自己构造一种数据类型结构体类型,把多个数据项(类型可以相同也可以不相同)组合在一起,作为一个整体进行处理。 根据本题的情况,用以下形式构造名为student的结构体类型。,返 回,下一页,上一页,9.1 一个程序实例,struct student /*student为结构体类型名*/ int num; /*学号为int型*/ char name10 /*姓名用字符数组*/float s

3、1,s2,score; /*3个成绩为float型*/ ; struct student是一种结构体类型,它由5个数据项组成,此处的数据项称为结构体成员或者域。接下来可以用struct student这个数据类型定义变量,只有变量才能存储数据。 例如,下面语句定义了一个结构体变量:struct student wang; 结构体变量wang包括学号、姓名、平时成绩、期末成绩和总评成绩等5个成员。程序中结构体变量不能整体引用,要引用到其中的成员。 结构体变量中成员的引用形式为:结构体变量.成员名。比如:wang.num、wang.name、wang.s1等。结构体成员在程序中的作用和用法与普通变

4、量相同。,返 回,下一页,上一页,9.1 一个程序实例,【程序代码】 #include “stdio.h“ #include “string.h“ struct student /*定义结构体类型*/ int num;char name10;float s1,s2,score; ; main() struct student wang; /*定义结构体变量*/,返 回,下一页,上一页,9.1 一个程序实例,/*以下给变量名为wang的学生赋值 */wang.num=101;strcpy(wang.name,“wanghai“);wang.s1=92.0;wang.s2=87.5;wang.sc

5、ore=wang.s1*0.3+wang.s2*0.7; /*计算总评成绩*/ /*以下输出该学生信息*/printf(“NO.:%dn“,wang.num);printf(“NAME:%sn“,wang.name);printf(“s1=%7.2f,s2=%7.2f,score=%7.2fnn“,wang.s1,wang.s2,wang.score); ,返 回,下一页,上一页,9.1 一个程序实例,程序输出结果为:在解决实际问题时经常需要使用结构体类型。使用时先定义结构体类型,然后再定义结构体变量或结构体数组。,返 回,9.2 结构体类型的使用,一组相关的数据可能是相同类型的,也可能是不同

6、类型的。为了封装相关的数据,就需要采用可以包含不同类型成员的类型来定义这样的数据,这种类型就是结构体类型。 9.2.1 结构体类型的定义 定义结构体类型的一般形式为: struct 结构体类型名类型名1 成员名1;类型名2 成员名2;类型名1 成员名1; ;,返 回,下一页,上一页,9.2 结构体类型的使用,例如: struct stud int num;char name20;char sex;int age;float score3;char address30;,返 回,下一页,上一页,9.2 结构体类型的使用,说明: (1)struct是关键字,标志结构体类型。struct后面是所定义

7、的结构体类型的名字,结构体名应符合标识符的命名规则。这里结构体名可以省略,省略后将成为无名结构体。 (2)结构体的各个成员用花括号括起来,结构体成员的定义方式和变量的定义方式一样,成员名的命名规则和变量相同;各成员之间用分号分隔;结构体类型的定义以分号结束。 (3)结构体成员的数据类型可以是基本类型的,也可以是构造类型,如数组或其他结构体类型。提示:结构体类型定义后面的分号“;”不能省略,它经常被遗漏而导致程序错误。,返 回,下一页,上一页,9.2 结构体类型的使用,9.2.2 结构体变量的定义及引用 有了结构体数据类型,接下来需要定义结构体类型变量,以便存放结构体类型的数据。 1. 结构体变

8、量的定义 C语言中,结构体变量定义可以采取3种方法。 (1) 先声明结构体类型再定义变量名 例如: struct stud /*定义结构体类型*/ int num;char name20;char sex;int age;float score3;,返 回,下一页,上一页,9.2 结构体类型的使用,char address30; struct stud student1,student2; /*定义结构体变量*/ 以上定义了两个结构体变量student1和student2,它们均包含6个成员:编号、姓名、性别、年龄、3门课成绩和地址。 与普通变量一样,结构体变量也可以通过初始化赋值。例如: s

9、truct stud student1=101,“ghz“,M,18,75.4,89.3,92.5,“xian“; struct stud student2=102,“xhy“,M,16,95.1,99,92,“beijing“; 结构体变量student1和student2中各成员的赋值情况如图9-1所示。,返 回,下一页,上一页,9.2 结构体类型的使用,注意:上面定义的结构体类型有6个成员,而赋值的时候有8项数据,原因是第5个成员score是数组,它有3个元素,用来存放3门课成绩。 从图9-1中可以看到,各成员分配在连续的存储区域内,而且各个成员所占的字节数之和就是结构体变量的字节数。

10、(2) 定义结构体类型的同时定义结构体变量 这种方法定义的一般形式为: struct 结构体名 成员表列 变量名表列;,返 回,下一页,上一页,9.2 结构体类型的使用,例如,上面的结构体类型struct stud也可以采取以下形式定义: struct stud int num;char name20;char sex;int age;float score3;char address30; student1=101,“ghz“,M,18,75.4,89.3,92.5,“xian“,student2; 这里只对变量student1进行了赋初值操作。,返 回,下一页,上一页,9.2 结构体类型的

11、使用,(3) 定义无名结构体类型的同时定义结构体变量(即不出现结构体名) 一般定义形式为: struct 成员表列 变量名表列; 例如: struct int num; char name20;char sex;,返 回,下一页,上一页,9.2 结构体类型的使用,int age;float score3; char address30;student1,student2; 2. 结构体变量中成员的引用 结构体变量本身不能代表一个特定的值,只有它的成员才会有特定的值。因此使用结构体变量时,要引用其成员。 结构体变量中成员的引用形式是: 结构体变量.成员名 例如,结构体变量student1中各个成

12、员引用形式如下: student1.num、student1.name、student1.sex、student1.age、student1.address,返 回,下一页,上一页,9.2 结构体类型的使用,student1.score0、student1.score1、student1.score2 结构体中成员的作用与地位相当于普通变量,因此可以进行与普通变量一样的操作,比如赋值、输入输出等,例如有以下语句: student1.num=101; scanf(“%d”,返 回,下一页,上一页,9.2 结构体类型的使用,3. 结构体类型嵌套 以上给出的例子中,结构体成员的类型都是基本类型和数组

13、类型。实际上,成员的类型可以是任何数据类型。下面给出成员类型是另一个结构体类型的例子。 例如: struct date /*日期结构*/int year;int month;int day; struct student,返 回,下一页,上一页,9.2 结构体类型的使用, int num;char name20;char sex;int age;struct date birthday; /* struct date为结构体类型*/char address30;stu=102,“xhy“,M,16,1977,5,8,“beijing“; 上例中结构体变量stu的存储结构如图9-2所示。,返 回

14、,下一页,上一页,9.2 结构体类型的使用,当成员本身又属于一个结构体类型,引用时要逐级找到最低一级成员,只能对最低级的成员进行赋值或存取操作。 例如,对上面定义的结构体变量stu,可以这样访问其中的日期成员:stu. birthday. yearstu.birthday.month stu.birthday. day 注意:不能用stu.birthday来访问stu变量中的成员birthday,因为birthday本身也是一个结构体变量。,返 回,下一页,上一页,9.2 结构体类型的使用,9.2.3 结构体数组 在例9-1中一个结构体变量只能处理一个人的信息(如一个学生的学号、姓名、成绩等数

15、据)。但在实际应用中经常需要处理一批人的信息,这时应该使用结构体类型的数组。 定义结构体数组与定义结构体变量的方法相同。例如: struct studentint num;char name20;char sex;int age;float score3;,返 回,下一页,上一页,9.2 结构体类型的使用,char address30; stu3; 以上定义了一个数组stu,它有3个元素stu0、stu1、stu2,类型均为struct student类型。结构体数组中成员的引用方式与结构体变量相同,下面以元素stu0为例,给出各个成员的引用形式: stu0.num、stu0.name、stu

16、0.sex、stu0.age stu0.address stu0.score0、 stu0.score1、 stu0.score2 可见,结构体数组元素也是通过数组名和下标来引用的。因为各个元素都是结构体类型,因此对结构体数组元素的引用与对结构体变量的引用一样,也要逐级引用,只能对最低的成员进行存取和运算。,返 回,下一页,上一页,9.2 结构体类型的使用,【例9-2】候选人得票统计程序。设有3个候选人,10个投票人,输入得票人的名字并进行统计,最后输出各人得票结果。 #include “string.h“ #include “stdio.h“ struct person char name2

17、0; /*候选人姓名*/int count; /*候选人票数*/ leader3=“star“,0, “mery“,0, “sun“,0; /*定义结构体数组并初始化*/ main( ) ,返 回,下一页,上一页,9.2 结构体类型的使用,int i,j;char leader_name20;for(i=1;i=10;i+)scanf(“%s“,leader_name); for(j=0;j3;j+)if(strcmp(leader_name,leaderj.name)=0) /*比较输入的名字与侯选人的名字*leaderj.count+; /*相当于leaderj.count= leader

18、j.count +1;*/ printf(“n“);,返 回,下一页,上一页,9.2 结构体类型的使用,for(i=0;i3;i+)printf(“%5s:%dn“,leaderi.name,leaderi.count); 程序运行结果为:,返 回,下一页,上一页,9.2 结构体类型的使用,程序定义了一个结构体数组leader,它有3个元素,每一个元素包含两个成员name(候选人姓名)和count(得票数),在定义数组时使之初始化,使3位候选人的票数都先置零。 主函数中定义了字符数组leader_name,它接受被选人的姓名,在10次循环中每次先输入一个被选人名,然后与3个候选人名相比,决定是

19、否计数。在输入和统计结束之后,将3人的名字和得票数输出。小测验 统计选票时,如果投票人数不确定,程序该如何修改?,返 回,下一页,上一页,9.2 结构体类型的使用,9.2.4 结构体指针 结构体指针是指基类型为结构体类型的指针变量。通过结构体指针可以间接访问结构体中的成员。 下面通过实例说明结构体指针的应用。 【例9-3】使用结构体指针输出学生基本信息。 【程序代码】 #include “string.h“ #include “stdio.h“ main( ) struct student /* 定义一个结构体类型*/ ,返 回,下一页,上一页,9.2 结构体类型的使用,long num; c

20、har name20;char sex;float score; ;struct student stu,*p; /* 定义结构体变量stu和结构体指针p */ p=,返 回,下一页,上一页,9.2 结构体类型的使用,printf(“No.:%ldnname:%snsex:%cnscore:%fn“,stu.num,stu.name,stu.sex,stu.score);printf(“No.:%ldnname:%snsex:%cnscore:%fn“,(*p).num,(*p).name,(*p).sex,(*p).score); 程序运行结果为:,返 回,下一页,上一页,9.2 结构体类型

21、的使用,程序分析: 程序中将结构体变量stu的地址赋给指针变量p,也就是使p指向stu,然后对stu的各成员赋值,第一个printf()函数输出stu的各个成员的值,第二个printf函数也是用来输出stu各成员的值,但使用的是(*p).num这样的形式。 通过结构体指针引用成员的方式有两种: (*p).成员名 p-成员名 (-为指向运算符) 指针变量可以指向结构体变量,当然也可以指向结构体数组,其使用方法与指向数组的指针的使用方法类似,只不过把普通数组换成了结构体数组。,返 回,下一页,上一页,9.2 结构体类型的使用,【例9-4】使用指向结构体数组的指针实现多名学生信息的输出。 【程序代码

22、】 #include “stdio.h“ struct student int num;char name20;char sex;int age; ; struct student stu3=101,“Xuhy“,M,18,102,“Liuhm“,M,19,103,“Lp“,F,20; main( ),返 回,下一页,上一页,9.2 结构体类型的使用,struct student *p; /* 定义结构体指针*/printf(“ No. Name sex agen“);for(p=stu;pnum,p-name,p-sex,p-age); 程序运行结果为:,返 回,下一页,上一页,9.2 结构

23、体类型的使用,程序分析: p是指向struct student结构体类型的指针变量。在for语句中先使p的初值为stu,即数组stu的起始地址,循环第一次输出stu0的各个成员值,然后执行p+,使p自加1(以struct student结构体类型所占的字节数为单位)后指向stu1,循环第二次输出stu1的各成员值,再执行p+后,p指向stu 2,输出stu 2的各成员值后循环结束。,返 回,9.3 链表,9.3.1 链表的基本结构 链表是一种动态数据结构,可根据需要动态地开辟存储空间,随时释放不再需要的存储空间。这样可以有效利用存储空间,提高存储空间利用率。 图9-3是一种单向链表结构示意图。

24、链表中的每个元素称为链表的结点,每个结点中包括两部分内容,即用户需要的数据和下一个结点的地址,也就是说,链表中的每个结点是由数据域和指针域组成。 在链表中通常用一个指针指向链表开头的结点,该指针称为头指针。图9-3中head即为头指针,它指向第一个结点。 单向链表中前一个结点的指针域指向后一个结点,这样可以通过前一个结点引用后一个结点。最后一个结点不再指向其他结点,称为尾结点(即表尾),它的指针域的值是NULL(空指针),表示整个链表到此结束。,返 回,下一页,上一页,9.3 链表,从链表的特点来看,结构体类型最适合描述链表。比例,有以下结构体类型定义: struct node int num

25、; float score; struct node *next; ; 其中成员num和score用来存放结点中的有用数据(即数据域),next是指针域,它的类型是struct node类型,用来指向一个结点。 【例9-5】建立一个简单链表,它由3个存放学生数据(包括学号和姓名)的结点组成,然后输出各个结点数据。,返 回,下一页,上一页,9.3 链表,【程序代码】 #include “stdio.h“ struct node int num; /* 存储学生学号 */float score; /* 存储学生成绩 */struct node *next; /* 定义结构体指针,指向下一个结点 *

26、/ ; main( ) struct node a,b,c,*head,*p;,返 回,下一页,上一页,9.3 链表,a.num=101;a.score=85.4; /* 给结点a的num和score域赋值 */b.num=103;b.score=96.1; /* 给结点b的num和score域赋值 */c.num=105;c.score=77.5; /* 给结点c的num和score域赋值 */head= /* 使p指针指向第1个结点 */do /* 依次输出各结点数据 */,返 回,下一页,上一页,9.3 链表,printf(“学号:%d 成绩:%5.2fn“,p-num,p-score)

27、; p=p-next; /* 指针p后移,指向下一结点 */while (p!=NULL); 程序运行结果为:程序说明: 本例中链表结点是在程序中定义的,不是临时开辟,这种方法生成的链表成为静态链表。当然,有使用价值的应该是动态链表。,返 回,下一页,上一页,9.3 链表,9.3.2 链表的基本操作 1. 动态分配和释放存储区 动态开辟存储空间需要使用malloc()函数,释放存储空间使用free()函数。这些函数包含在头文件”stdlib.h”中。 (1)malloc()函数 函数调用的一般形式为:malloc(size) 功能:在内存申请分配一个size字节的存储区。调用结果为新分配的存储

28、区的首地址,是一个void *类型指针,若申请失败,则返回NULL。 void *类型指针是一个指向非具体数据类型的指针,称为无类型指针,因此一般在使用该函数时,要用强制类型转换将其转换为所需要的类型。例如:,返 回,下一页,上一页,9.3 链表,int *p; p=(int *)malloc(2); 上面语句完成向内存申请2字节的存储区,用来存放1个整数,并让指针p指向存储区的首部。 struct node *p; p=(struct node *)malloc(sizeof(struct node); 上面语句中sizeof是C语言的运算符,功能是计算数据类型或变量所占的字节数,sizeo

29、f(struct node)是计算struct node类型所占的字节数,那么malloc(sizeof(struct node)的功能是申请分配一个struct node类型所需大小的存储区。由于malloc()的返回值是无类型指针,而指针p的基类型是struct node类型,因此需要进行强制类型转换,将malloc()函数的返回值转换为指向struct node类型的指针。,返 回,下一页,上一页,9.3 链表,(2)free()函数 函数调用的一般形式为:free(p) 功能:释放指针p所指向的动态存储区。 2. 建立单向链表 建立动态链表是指在程序执行过程中从无到有地建立起一个链表,

30、即一个一个地开辟结点和输入结点数据,并建立起前后链接关系。 【例9-6】建立链表函数。建立一个有若干名学生数据的单向动态链表,当输入的学生学号为0时结束操作。 【程序代码】 #include “stdio.h“ #include “stdlib.h“ struct node,返 回,下一页,上一页,9.3 链表,int num;float score;struct node *next; ; struct node *create( ) struct node *head,*s,*p;int c;float x;head=(struct node *)malloc(sizeof(struct

31、node); /*生成头结点*/,返 回,下一页,上一页,9.3 链表,p=head; /*尾指针指向第一个结点*/printf(“输入学生结点信息(学号和成绩),学号为0时输入结束:n“);scanf(“%d%f“, /*将新结点s插入到表尾*/,返 回,下一页,上一页,9.3 链表,p=s; /*修改尾指针p指向当前的尾结点*/scanf(“%d%f“, /*返回头指针*/ 程序分析: (1)本例链表建立采用的是尾插法,即新结点始终链接在链表的尾部。 (2)链表建立的具体过程为:首先用malloc()函数申请头结点,并将指针p也指向头结点,如图9-5 (a)所示,然后输入学生数据,判断学号

32、是否为0,并由此进入循环体,在循环体中为新结点s申请空间并存入数据,如图9-5 (b)所示,将新结点链接到链表尾部,如图9-5 (c),,返 回,下一页,上一页,9.3 链表,移动指针p使其指向新的链尾结点,如图9-5 (d),然后开始下一轮操作,如图9-5 (e)和如图9-5 (f)所示,如此反复,当用户输入0时候,表示操作结束,此时p依然指向链表的结尾,将其指针域置为NULL,整个链表建立结束,返回头指针。2. 输出链表 【例9-7】输出链表函数。 【程序代码】 void print(struct node *head) struct node *p;printf(“t输出学生结点信息n“

33、);,返 回,下一页,上一页,9.3 链表,p=head-next; /* 指针p指向第1个结点 */while (p!=NULL)printf(“学号:%d成绩:%5.1fn“,p-num,p-score);p=p-next; /* 指针p后移,指向下一结点 */ 3. 删除链表中的结点 从链表中删去一个结点,首先要找到这个结点,然后把它从链表中分离开来,撤销原来的链接关系,同时保证原有链表的链接关系。 【例9-8】删除结点函数,删除链表中学号为num的结点。,返 回,下一页,上一页,9.3 链表,【编程思路】 (1)删除结点操作分两步完成。第一步查找要删除的结点,第二步进行删除。 (2)查

34、找结点时,从p指向的第一个结点开始,检查该结点中的num值是否等于输入的要求删除的那个学号,如果相等,就找到了要删除的结点,如不相等,就将p后移一个结点,直到找到要删除的结点或者遇到链尾为止。在移动p的同时移动q,使用q记录p的前驱结点,如图9-6 (a)所示。 (3)找到待删除结点后,使q指向要删除结点p的后继结点,如图9-6(b)所示,然后释放结点p的内存空间,如图9-6(c)所示。,返 回,下一页,上一页,9.3 链表,【程序代码】 struct node *del(struct node *head,int num) struct node *p,*q;q=head;p=head-ne

35、xt;while(num!=p-numif(num=p-num),返 回,下一页,上一页,9.3 链表,q-next=p-next;free(p);elseprintf(“没有找到学号为%d的结点!n“,num);return(head); 4. 在链表中插入结点 对链表的插入是指将一个结点插入到一个已有的链表中,为了能做到正确插入,必须解决两个问题:如何找到插入的位置;如何实现插入。,返 回,下一页,上一页,9.3 链表,【例9-9】插入结点函数。假定原链表结点已经按学号从小到大排列。 【程序代码】 struct node *ins(struct node *head,int c,float

36、 x) struct node *p,*q,*s;s=(struct node *)malloc(sizeof(struct node); /*生成新结点s*/s-num=c; /*将要插入的学生学号存放到新结点s的数据域中*/s-score=x; /*将要插入的学生成绩存放到新结点s的数据域中*/q=head;,返 回,下一页,上一页,9.3 链表,p=head-next;while (p!=NULL ,返 回,下一页,上一页,9.3 链表,程序分析: 首先定义一个新结点存储待插入的结点信息(如图9-7中的结点s),从指针p指向第一个结点开始,将p-num与c相比较,如果cp-num,将p后

37、移,并使q始终指向p的前驱结点,如图9-7(a)所示,直到p-num-c为止,这时找到新结点的插入位置。 如果插入位置是链表的尾部,将新结点插到链尾即可。 如果插入位置在链表中间,则让s-next指向p结点,如图9-7(b)所示,然后让q-next 指向s结点,如图9-7(c)所示。,返 回,下一页,上一页,9.3 链表,9.3.3 链表综合应用 【例9-10】编制主函数,调用链表建立函数,输出函数,删除函数及插入函数,完成链表的基本操作。 【程序代码】 main( ) struct node *h;int del_num,in_num;float in_score;h=create(); /

38、*建立链表*/print(h); /*输出链表*/,返 回,下一页,上一页,9.3 链表,printf(“n输入要删除的学生结点的学号:n“); scanf(“%d“, /*输出链表*/ ,返 回,下一页,9.3 链表,程序运行过程为:,返 回,上一页,9.4 结构体应用实例,【例9-10】某班有45名学生,现在对他们的期末考试成绩进行统计。假定期末考3门课,分别为物理、数学和化学,要求计算每个学生的平均成绩和总成绩,最后计算本班每门课的平均成绩。 【编程思路】 (1)本程序分成三部分:学生数据输入(包括计算学生平均成绩和总成绩)、学生成绩单输出、本班每门课总成绩和平均成绩的计算和输出,分别由

39、三个函数来实现,在主程序中调用这三个函数。 (2)定义结构体来存储学生数据,包括学生基本信息,学生三门课成绩(利用数组),平均成绩,总成绩。 (3)将结构体数组地址作为实参传递给函数,以便在函数中使用结构体指针对学生数据进行操作。,返 回,下一页,9.4 结构体应用实例,【程序代码】 #include “stdio.h“ #include “conio.h“ #include “string.h“ #define NU 3 /*以3名学生为例*/ struct student long num; /*定义成员变量,存储学生学号*/char name10; /*定义成员变量,存储学生姓名*/fl

40、oat score3; /*定义成员变量,存储学生3门课的成绩*/float aver_person; /*定义成员变量,存储学生平均成绩*/ float sum_person; /*定义成员变量,存储学生总成绩*/ ;,返 回,上一页,下一页,9.4 结构体应用实例,void print(struct student *p) /*输出个人成绩单 */ int i;for(i=0;inum);printf(“t姓名:%sn“,p-name);printf(“t数学:%5.1f |“, p-score0);printf(“ 物理:%5.1f |“, p-score1);printf(“ 化学:%

41、5.1fn“, p-score2);printf(“t平均成绩:%5.1fn“, p-aver_person);,返 回,上一页,下一页,上一页,9.4 结构体应用实例,printf(“t总成绩:%5.1fn“, p-sum_person);printf(“-n“); void scan(struct student *p) /*输入学生数据同时计算个人的平均成绩和总成绩 */ int i,j;printf(“ 学生信息录入n“);for(i=0;iNU;p+,i+),返 回,下一页,上一页,9.4 结构体应用实例,p-sum_person=0;printf(“学号:“);scanf(“%ld

42、“, /*输入学生第j门课成绩*/,返 回,下一页,上一页,9.4 结构体应用实例,p-sum_person=p-sum_person+p-scorej; /*学生成绩累加求和*/ p-aver_person=p-sum_person/3; /*计算单个学生的平均成绩*/ printf(“-n“); void average(struct student *p) /* 计算本班每门课的总成绩和平均成绩 */ ,返 回,下一页,上一页,9.4 结构体应用实例,int i,j;float sum3=0,aver3;for(i=0;i scorej; /*学生成绩累加求和*/for(j=0;j3;j

43、+)averj=sumj/3; /*分别计算每门课的平均成绩*/printf(“tt 本班成绩信息统计n“);printf(“t数学总成绩:%7.1f,平均成绩:%5.1f n“, sum0,aver0);printf(“t物理总成绩:%7.1f,平均成绩:%5.1f n“, sum1,aver1);,返 回,下一页,上一页,9.4 结构体应用实例,printf(“t化学总成绩:%7.1f,平均成绩:%5.1f n“, sum2,aver2);printf(“-n“); void main( ) struct student stuNU;scan (stu); /*调用函数scan (),输入

44、学生信息并计算平均成绩*/print(stu); /*调用函数print(),输出学生成绩单*/average(stu); /*调用函数average(),计算并输出全班的平均成绩*/ ,返 回,下一页,上一页,9.4 结构体应用实例,程序测试时以3个学生为例,即NU=3,运行结果为:,返 回,下一页,上一页,9.4 结构体应用实例,程序分析: 由于要处理的不是一个学生的信息,而且每个学生的信息也不止一条,每条学生信息的数据类型也不一样,所以使用结构体数组存储数据。 为了程序的层次清晰、修改和维护方便,本程序采用模块化结构,用3个函数实现不同的功能,而且使用结构体地址作为函数的参数,这样可以在

45、函数中通过结构体数组指针对结构体数组成员进行操作。 主函数中的stu就是结构体数组stu的首地址,而在各个函数中的形参p是结构体指针变量,实参和形参的传递方式就是地址传递。这样在函数中指针p的各种操作就可以理解成直接对stu这个结构体数组的操作。,返 回,9.5 本章小结,通过本章学习,读者应掌握以下内容: 1. 结构体类型的概念。把多个不同类型的数据组合在一起表示一个对象时,可以用结构体类型实现。 2. 结构体变量、结构体数组、结构体指针的定义与使用。结构体变量一般不能整体引用,需要引用到成员,结构体成员与普通变量的用法相同。 结构体成员有3种引用形式,例如: struct date int

46、 year, month, day;d, *p= (1) 用结构体变量名的引用形式:d.year d.month d.day,返 回,下一页,上一页,9.5 本章小结,(2) 用结构体指针变量的引用形式:(*p).year (*p).month (*p).dayp-year p-month p-day 3. 结构体类型作函数参数。实参为结构体类型数据时,形参也应该是同结构的结构体类型。 4. 链表。链表是一种动态存储结构,可根据需要动态地开辟存储空间,随时释放不再需要的存储空间。链表的基本操作有创建链表,输出链表,在链表中插入新结点,删除链表中的废弃结点。 5. 用结构体类型解决实际问题的方法

47、。,返 回,9.6 实训,实训1 【实训内容】结构体程序设计 【实训目的】使用结构体编写程序,解决简单问题 【实训题目】下面程序的功能是计算某日在本年中是第几天。阅读程序并上机调试。 编程点拨 (1)定义一个结构体变量(包括年、月、日)解决日期的存储问题。 (2)判断输入的年份是否是闰年,因为闰年的2月是29天。 (3)计算用户输入的月份之前的天数,这些月份都是整月的。 (4)将整月的天数和当前日子加上就是我们要计算的天数。 参考程序代码,返 回,下一页,上一页,9.6 实训,#include “stdio.h“ struct birthdayint year;int month;int day; ; main( )struct birthday td;int i,sum=0;int a13=0,31,28,31,30,31,30,31,31,30,31,30,31;printf(“请输入年份:“);scanf(“%d“,返 回,下一页,上一页,9.6 实训,printf(“请输入月份:“);scanf(“%d“, ,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报