版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言程序设计项目8利用结构体实现项目目标TARGET知识目标掌握结构体、共用体和枚举类型数据的使用。掌握C程序的实现过程和结构
能够使用typedef进行类型定义
掌握结构体类型和变量的定义及应用掌握共用体类型的定义及应用
枚举类型的定义及应用目标TARGET技能目标会使用结构体、共用体和枚举类型数据能够使用不同的数据类型解决实际问题用结构体实现数据的增加、删除、修改和显示任务8.1任务8.1用结构体实现数据的增加、删除、修改和显示
任务描述本项目任务是对学生成绩管理系统进行数据结构设计,即解决学生成绩信息的存储结构,编写代码实现系统的各功能模快。任务分析要实现系统的各功能模块,必须确定信息的存储结构。学生的基本信息包括:学号、姓名、3门课程成绩、总成绩等,所以,存储结构的核心是定义学生基本信息的类型。那么本案例的任务是:(1)定义学生基本信息的结构类型;(2)确定学生成绩信息的存储变量,(3)编写代码实现各模块功能。1认识结构体Part◎结构体类型◎结构体数组◎结构体和函数参数的传递◎结构体概述◎共用体◎枚举类型◎类型定义◎学生成绩管理系统的实现结构体概述
结构体是一种构造类型,它是由若干成员组成,每个成员可以具有不同的数据类型。所以说,结构体是若干个类型相同或不同数据项的集合。例如,学生的基本信息包含以下数据项:学号(no)、姓名(name)、数学(math)、语文(yw)、英语(eng)和总分(sum)。那么这个类型就应该如图8-1所示。结构体类型
结构体类型,是将该结构体的所有成员的类型说明按约定的方法结合在一起,结构体的各个元素(常称之为成员)可以是不同的数据类型。1.结构体类型的形式定义结构体类型的一般形式为:struct结构类型名{类型名成员名1;类型名成员名2;…类型名成员名n;};结构体类型
例如:structStudent{char*name;//姓名intnum;//学号floatmath;//数学floatyw;//语文floateng;//英语};说明:(1)成员声明语法同变量,示例:数据类型成员名;(2)字段的类型可以为:基本类型、数组或指针、结构体等结构体类型
2.结构体变量的定义结构体类型定义后,就可以用它来定义相应的结构体变量。定义结构体类型变量有以下两种方法:(1)间接定义法先定义结构体类型,再定义结构体变量.struct结构类型名{成员列表;};结构体变量的定义:struct结构类型名变量名;例如,使用8.1.1定义的结构体类型student来定义学生结构体变量,语句: structstudentstu1; structstudentstu2;结构体类型
(2)直接定义法在定义结构体类型的同时定义变量。定义的一般形式为:struct[结构类型名] /*结构类型名可缺省*/{类型名成员名1;类型名成员名2;…类型名成员名n;}变量名表;例如:structStudent{char*name;//姓名intnum;//学号floatmath;//数学结构体类型
floatyw;//语文floateng;//英语}stu1,stu2;结构体类型
3.结构体变量的引用(1)简单结构变量的引用结构体变量的使用是通过对其每个成员的引用来实现的,一般形式如下:结构体变量名.成员名其中,“.”是结构体的成员运算符,它在所有运算符中优先级最高,因此,上述引用结构体成员的写法可以作为一个整体看待。结构体变量中的每个成员都可以象同类型的普通变量一样进行各种运算。(2)同类型结构变量间的引用ANSIC新标准允许将一个结构类型的变量,作为一个整体赋给另一个具有相同结构类型的变量。如有定义:structstudentstud1,stud2;结构体类型
4.结构体变量的初始化在定义结构变量的同时,允许对结构变量初始化,但要注意结构成员的数据类型与初值一致。例如:structCStudent{ longno;/*学号*/ charname[16];/*姓名*/ intage; /*年龄*/ intscore;/*成绩*/}stu={2013001,"ZhanSan",17,80};结构体类型例8-1考试结束后老师登记学生成绩,学生的基本信息包括姓名(chName)、期中成绩(iMiddle)、期末成绩(iFinal)和总评成绩(fAve),要求输入两个同学的期中、期末成绩,将平均分数较高的同学的成绩单输出。(1)定义一个结构体类型,同时定义两个结构体变量(2)从键盘输入两个变量的chName,iMiddle,iFinal等成员值(3)分别计算平均分数(4)比较平均分,将平均分数较高的同学的成绩单输出到屏幕上
算法设计结构体类型程序代码#include"stdio.h"voidmain(){structstudent{charchName[8];intiMiddle,iFinal;floatfAve;}stStu1,stStu2;/*直接定义法定义结构体类型及变量*/scanf("%s%d%d",stStu1.chName,&stStu1.iMiddle,&stStu1.iFinal);
结构体类型scanf("%s%d%d",stStu2.chName,&stStu2.iMiddle,&stStu2.iFinal);stStu1.fAve=(stStu1.iMiddle+stStu1.iFinal)/2.0;stStu2.fAve=(stStu2.iMiddle+stStu2.iFinal)/2.0;if(stStu1.fAve>stStu2.fAve)printf("%s:%d%d%0.1f",stStu1.chName,stStu1.iMiddle,stStu1.iFinal,stStu1.fAve);elseprintf("%s:%d%d%0.1f",stStu2.chName,stStu2.iMiddle,stStu2.iFinal,stStu1.fAve);getch();}结构体数组1.结构体数组的定义结构体数组的定义与结构体变量类似,只是结构体变量替换成数组。定义结构体数组的一般形式如下struct结构体名{成员列表;}数组名[元素个数];或:struct结构体名数组名[元素个数];结构体数组2.结构体数组的引用结构体数组元素也是通过数组名和下标来引用的,但其元素是结构体类型的数据,因此,对结构体数组元素的引用与对结构体变量的引用一样,也是逐级引用,只能对最低级的成员进行存取和运算。结构体数组的引用的一般形式为: 数组名[下标].成员名结构体数组3.结构体数组的初始化结构数组也可以在定义时进行初始化,其方法是在定义结构数组的之后紧跟等号和初始化数据。 其一般形式是:struct结构体类型结构数组名[n]={{初值表1},{初值表2},…,{初值表n}};结构体数组例8-2一个学习小组有N名学生,学生的信息包含学号、姓名、语文、数学、英语三门课的成绩,从键盘上输入N名学生的信息,要求统计总成绩并显示总分最高的学生信息。(1)以学生的信息数据项为成员,定义结构体类型和相应的结构体数组;(2)循环输入每个学生的信息,统计总成绩,存储在结构体数组中;(3)循环比较求出总分最高的学生,并显示。
算法设计结构体数组程序代码#include"stdio.h"#defineN3/*学生人数*/structstudent{chariId[15];charchName[15];intiChinese,iMath,iEnglish;intiTotal;};结构体数组voidmain(){inti,iMax=0;structstudentstStu[N]={{"06003","Tom",80,85,80},{"06005","Alice",90,80,95},{"06002","Ellen",80,78,59}};/*定义结构体数组并且初始化*/for(i=0;i<N;i++)/*循环计算每个学生的总分*/{stStu[i].iTotal=stStu[i].iChinese+stStu[i].iMath+stStu[i].iEnglish;
结构体数组for(i=0;i<N;i++)/*求出总分最高的学生的数组元素下标*/{if(stStu[i].iTotal>stStu[iMax].iTotal)iMax=i;}printf("\nThebeststudent'sinformation:\n");printf("%s,%s,%d,%d,%d,%d",stStu[iMax].iId,stStu[iMax].cName,stStu[iMax].iChinese,stStu[iMax].iMath,stStu[iMax].iEnglish,stStu[iMax].iTotal;结构体数组for(i=0;i<N;i++)/*求出总分最高的学生的数组元素下标*/{if(stStu[i].iTotal>stStu[iMax].iTotal)iMax=i;}printf("\nThebeststudent'sinformation:\n");printf("%s,%s,%d,%d,%d,%d",stStu[iMax].iId,stStu[iMax].cName,stStu[iMax].iChinese,stStu[iMax].iMath,stStu[iMax].iEnglish,stStu[iMax].iTotal;getch();}
结构体和函数参数的传递1.结构体变量作为函数参数结构体变量作为一个整体可以传递给函数以及由函数返回,作为函数参数时形参实参都应是结构体类型,返回值为结构体类型时,函数应定义为结构体类型,声明方式如下:struct结构体类型函数名(结构体类型参数,结构体类型参数2);如无返回值则函数定义为void类型。结构体和函数参数的传递例8-3修改例8-1,要求在函数中实现计算、比较平均分并且显示平均分数较高的学生信息的功能。(1)定义外部结构体类型;(2)声明用户自定义函数;(3)在主函数中输入数据并且调用函数。
算法设计结构体和函数参数的传递程序代码#include"stdio.h"structstudent{charcName[8];intiMiddle,iFinal;floatfAve;};/*由于在多个函数中应用,所以结构体类型定义为外部*/voidfnBest(structstudentstS1,structstudentstS2);/*显示平均分较高学生信息的函数*/voidfnBest(structstudentstS1,structstudentstS2)
结构体和函数参数的传递{stS1.fAve=(stS1.iMiddle+stS1.iFinal)/2.0;stS2.fAve=(stS2.iMiddle+stS2.iFinal)/2.0;if(stS1.fAve>stS2.fAve)
printf("%s:%d%d%0.1f",stS1.cName,stS1.iMiddle,stS1.iFinal,stS1.fAve);elseprintf("%s:%d%d%0.1f",stS2.cName,stS2.iMiddle,stS2.iFinal,stS2.fAve);}结构体和函数参数的传递{voidmain(){structstudentstA,stB;scanf("%s%d%d",stA.cName,&stA.iMiddle,&stA.iFinal);scanf("%s%d%d",stB.cName,&stB.iMiddle,&stB.iFinal);fnBest(stA,stB);/*以结构体变量为实参调用函数*/getch();}结构体和函数参数的传递2.结构体数组作为函数参数结构数组作为函数参数,与数组作为函数参数的处理方式完全相同。即采用“地址传递”方式,形参结构变量中各成员值的改变,对相应实参结构变量产生影响。结构体和函数参数的传递例8-4修改例8-2,在函数中将N个学生的数据输入并统计总分和求出最高分的学生并显示。(1)定义全局结构体类型structstudent;(2)声明用户函数fnInput和fnDisp;(3)编写fnInput程序实现输入N个学生信息并计算总分;(4)编写函数fnDisp求N个学生中总分最高的并且显示;(5)编写主函数定义结构体类型数组,调用函数实现输入题目要求。
算法设计结构体和函数参数的传递程序代码#include"stdio.h"#include"stdio.h"#defineN3/*表示学生人数*/structstudent{charcNo[15];/*存放学号*/charcName[15];/*存放姓名*/intiChinese,iMath,iEnglish;/*存放语文、数学、英语成绩*/
结构体和函数参数的传递intiTotal;/*存放总分*/};voidfnInput(structstudentstStud[],intn);/*输入学生信息并计算总分*/voidfnDisp(structstudentstStud[],intn);/*求总分最高的学生并显示其信息*/voidfnInput(structstudentstStud[],intn)/*输入学生信息并计算总分*/{inti;printf("pleaseinputthreestudents'information\n");
结构体和函数参数的传递for(i=0;i<n;i++){scanf("%s%s%d%d%d",stStud[i].cNo,stStud[i].cName,&stStud[i].iChinese,&stStud[i].iMath,&stStud[i].iEnglish);stStud[i].iTotal=stStud[i].iChinese+stStud[i].iMath+stStud[i].iEnglish;}}voidfnDisp(structstudentstStud[],intn)/*求总分最高的学生并显示其信息*/{
结构体和函数参数的传递inti=0,iMax=0;for(i=1;i<n;i++)if(stStud[i].iTotal>stStud[iMax].iTotal)iMax=i;printf("\nThebeststudent'sinformation:\n");printf("%s,%s,%d,%d,%d,%d",stStud[iMax].cNo,stStud[iMax].cName,stStud[iMax].iChinese,stStud[iMax].iMath,stStud[iMax].iEnglish,stStud[iMax].iTotal);}结构体和函数参数的传递voidmain(){structstudentstPerson[N];/*定义结构体数组*/fnInput(stPerson,N);/*调用函数,循环输入N个学生的信息并且计算其总分*/fnDisp(stPerson,N);/*调用函数,求出总分最高的学生的下标并显示*/getch();}
结构体和函数参数的传递3.函数的返回值是结构体类型变量结构体变量也可以作为函数的返回值,这时在函数定义时,需要说明返回值的类型为相应的结构类型。如:structStudentfnFuction(){ structStudentp; /*定义结构体变量p … /*省略其它操作语句*/ return(p); /*返回结构体变量p*/}其中,函数名“fnFuction”前面的类型说明符“structStudent”是用于对函数返回值P的类型进行说明的。共用体1.共用体变量的定义有时为了节省存储空间或为了用多种类型访问一个数据等原因,需要使几种不同类型的变量存放到同一段内存单元中。例如,把一个短整型变量i,一个字符变量ch和一个单精度实型变量f放在地址为1000的起始内存单元,i,ch,f分别占据2个,1个和4个字节,这种使用不同变量共占同一段内存的结构称为“共用体”类型的结构,共用体类型也是一种构造类型,与系统定义的数据的基本类型不同,它必须定义后才能使用。共用体类型定义的一般形式为:union共用体类型名 {数据类型成员1; 数据类型成员2;……数据类型成员n;};
共用体其中union是关键字,是定义共用体类型必不可少的标识符;共用体名是程序员自己命名的标识符。{}中的内容为共用体成员的类型说明,与结构体类型的成员说明相同。共用体的成员可以是任何类型,包括共用体类型和结构体类型。例如:uniondata{inti;charch;doublef;}; 共用体共用体变量的定义形式有三种:方式1:先定义共用体类型,后定义共用体变量,共用体变量定义形式为:union共用体类型名变量名;例如:uniondataa,b,c;
方式2:定义共用体类型的同时定义共用体变量,例如:uniondata{inti;charch;
共用体doublef;}a,b,c方式3:不用出现共用体名,直接定义共用体变量,例如:union{inti;charch;doublef;}a,b,c 共用体2.共用体变量的引用共用体变量的引用方式与结构变量的引用方式也非常类似。共用体变量中成员的引用形式为:共用体变量名.成员名例如,前面定义了共用体变量a后,则对其成员变量的引用分别为:a.i;
a.ch;
a.f;C语言最初引入共用体的目的之一是为了节省存储空间,另外一个目的是可以将一种类型的数据不通过显式类型转换而作为另一种类型数据使用。 枚举类型
在实际问题中,有些变量只有几种可能的取值。例如,一个星期只有7天,一年只有12个月,人的性别只有两种,等等。在C语言中对这样取值比较特殊的变量可以定义为“枚举”类型。在“枚举”类型的定义中列举出变量所有可能的取值,被定义为“枚举”,该类型的变量取值不能超过定义的范围。应该说明的是,“枚举”类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。 枚举类型1.枚举类型的定义枚举类型的定义形式如下:enum枚举类型名{取值表};enum是定义枚举类型的关键词。花括号中的取值表称为枚举表,取值为所有可能的取值,每个枚举表项是常量,各常量之间以逗号分隔,使用时不要在常量的两端加单、双引号。例如:enumweekday{sun,mon,tue,wed,thu,fri,sat};该枚举名为weekday,枚举常量共有7个,反被说明为weekday类型的变量取值只能是七天中的某一天。 枚举类型2.枚举变量的定义(1)先定义枚举类型,后定义枚举变量例如:enumcolor{red,yellow,blue,green,white,black};/*定义枚举类型*/
enumcolorc;/*定义枚举变量*/即:c定义为enumcolor型的枚举变量。(2)在定义枚举类型的同时定义枚举变量例如:enum[color]{red,yellow,blue,green,white,black}c,b;即:c、b定义为enumcolor型的枚举变量。此时,枚举类型名color可缺省。 类型定义
C语言提供了许多标准类型名,如int,char,float等。用户可以直接使用这些类型名来定义所需要的变量。同时C语言还允许使用typedef语句定义一种新的类型名来代替已有类型名,定义新的类型名称之后,可像标准数据类型那样用新的类型名称定义变量。 类型定义
1.定义基本类型的别名定义基本类型别名的形式为:typedef基本类型名别名标识符;例如:typedefintWORD;/*定义WORD为int的别名*/
typedeffloatREAL; /*定义REAL为float的别名*/
typdefunsignedcharBYTE;/*定义BYTE为unsignedchar的别名*/指定用WORD代表int类型,REAL代表float,BYTE代表unsignedchar。所以,以下两种形式对变量a、b和c的定义是等价的。(1)inta;floatb;unsignedcharc;
(2)WORDa;REALb;BYTEc;类型定义
2.定义自定义的数据类型的别名声明自定义类型别名的形式为:typedef自定义类型说明信息别名标识符;例如:typedefstructstudent{ longno; charname[16]; intage,score;}STUDENT;类型定义3.类型定义的步骤(1)按定义变量的方法,写出定义体;(2)将变量名换成别名;(3)在定义体最前面加上typedef。例如:给unsignedint定义一个别名DWORD。(1)按定义变量的方法,写出定义体:unsignedinta;(2)将变量名换成别名:unsignedintDWORD;(3)在定义体最前面加上typedef:typedefunsignedintDWORD;学生成绩管理系统的实现1.存储结构设计(1)确定学生基本信息的类型对学生的基本信息进行处理,首先需要把学生的基本信息,包括学号、姓名、3门课程成绩、总成绩等相关信息录入计算机,保存到相应的变量中,否则计算机无法对这些数据进行处理。2.数据录入与浏览(1)数据录入模块设计思路:将结构体数组作为函数的形参,已录入的记录总数m定义为全局变量。利用循环结构,交互式提示用户录入记录。同时,定义学号为关键字,程序需对录入的学号进行合法性检查,不能有重复的学号。学生成绩管理系统的实现(2)记录浏览模块对函数的形参进行操作,注意到记录的总数由全局变量m保存,按%-8.1f的格式输出记录。(3)运行测试编译、连接、运行程序。按数字键1选择“数据录入”菜单,按照系统提示录入若干条记录,如图8-1所示。再按8选择“记录浏览”菜单,系统将显示所有学生信息。如图8-2所示。学生成绩管理系统的实现3.记录查询与修改(1)记录查询设计思路:输入要查找的学生之学号,以学号为关键字,在结构数组中查找匹配,如果匹配成功,显示该学生的记录;否则提示未找到等提示信息。运行效果如图8-3所示。学生成绩管理系统的实现(2)记录修改
记录修改就是对指定的学号的学生,修改其它字段的数据。
设计思路:输入要修改的学生学号,以学号为关键字,首先查询确认该学生记录的存在性。如果该学号不存在,则提示相应提示信息;否则输入该学生的其它字段数据。拓展案例案例8-1结构体的应用问题描述现有一个同学的原始成绩单,内容包括学号、姓名、英语成绩、高等数学、程序设计三门课的成绩以及出生年月,请将其拷贝入另一个结构体变量进行备份,并且将数据输出进行核对是否备份正确。结构体类型算法设计(1)根据题意,定义结构体structdate描述出生年月(2)定义结构体描述structstudent描述学生信息,其中出生年月为structdate类型(3)定义两个structstudent变量stOrg和stBak,其中stOrg初始化赋值(4)将stOrg复制到stBak(5)输出stBak的各成员值,与stOrg的各初始化数据对比结构体类型程序代码#include"stdio.h"structdate{intiYear,iMonth,iDay;};/*定义表示日期的结构体类型*/structstudent{charcName[8];intiEng,iMath,iProg;structdatestBirth;};/*定义表示学生信息的结构体类型*/结构体类型程序代码voidmain(){structstudentstOrg={"Tom",80,90,85,1986,11,30},stBak;stBak=stOrg;/*同一个类型的结构体变量直接赋值*/printf("%s,%d,%d,%d,%d-%d-%d",stBak.cName,stBak.iEng,stBak.iMath,stBak.iProg,stBak.stBirth.iYear,stBak.stBirth.iMonth,stBak.stBirth.iDay);getch();}拓展案例案例8-2结构体的应用问题描述现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。请看下面的表格,使用共用体编程完成.拓展案例算法设计(1)根据题意,定义结构体structPerson描述学生和教师信息(2)其中score和course定义为共用体(3)定义结构数组(4)输入数组元素,根据职业进行判定是老师还是学生(5)输出相应信息拓展案例程序代码#defineTOTAL1//人员总数structPerson{charname[20];intnum;charsex;charprofession;union{floatscore;拓展案例charcourse[20];}sc;};voidmain(){inti;structPersonpersons[TOTAL];//输入人员信息for(i=0;i<TOTAL;i++){printf("Inputinfo:");拓展案例scanf("%s%d%c%c",persons[i].name,&(persons[i].num),&(persons[i].sex),&(persons[i].profession));if(persons[i].profession=='s'){//如果是学生scanf("%f",&persons[i].sc.score);}else{//如果是老师scanf("%s",persons[i].sc.course);//输出人员信息}fflush(stdin);}拓展活动各负其责,合作共赢通过对结构体学习,引导学生合作共赢,在团队中,每一个成员的角色都不可替代,要遵从团队规则,也要各负其责。项目小结(1)结构体可以表达类似于数据库中“记录”的数据,使用结构体来表达数据,必须先定义结构体类型,再用此类型定义结构体变量。结构体中的每个数据叫做成员,在进行输入输出等操作时要用成员引用符号“.”引用到具体成员。(2)定义一个结构体变量,系统分配的内存空间是该结构体变量中所有成员占据内存空间的总和。(3)结构体数组的每一个元素,都是结构体类型数据,均含结构体类型的所有成员。结构体数组元素通过数组名和下标来引用,但其元素是结构体体类型的数据,因此,对结构体数组元素的引用与对结构体变量的引用一样,也是逐级引用,只能对最低级的成员进行项目小结进行存取和运算。一般的引用形式为: 数组名[下标].成员名(4)结构体变量可以传递给函数以及由函数返回,作为函数参数的传递方式与简单变量作为函数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 金东区海棠东路武义江大桥改造工程桥梁荷载试验检测招标文件
- 信阳市2026届高三第二次联考语文试卷含解析
- 教育研究方法基础(第4版)课件 第7-12章 教育统计与教育测验-教育研究成果表述
- 【海口市L大酒店餐饮部员工满意度的影响因素研究11000字(论文)】
- 26年基础护理服务等级认定课件
- 【2026】软件资格考试信息处理技术员(基础知识、应用技术)合卷(初级)备考要点精析年
- 26年银发哮喘持续状态案例课件
- 26年银发疾病话题规避技巧课件
- GEO优化系统测评:2026年品牌提及率提升TOP3平台深度解析与选型指南
- 安全注射培训
- 再生资源绿色回收分拣中心项目投资计划书
- 2026智能物流仓储自动化升级与REITs融资模式研究
- 2026年内部审计师考试试卷及答案
- 四川省自然资源投资集团有限责任公司2026年上半年公开招聘考试备考试题及答案解析
- 2025年成都市网格员笔试试题及答案
- 2026年初级社会工作者《社会工作综合能力》通关模拟卷及参考答案详解(突破训练)
- (2026版)铁路货物运输规则课件
- 小学语文综合性学习课题设计
- 水利隐蔽工程验收记录表(示例版)
- XJJ013-2012 新疆维吾尔自治区城市规划管理技术规定
- 中海油校招笔试题库和答案
评论
0/150
提交评论