




已阅读5页,还剩27页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2019/7/12,1,高级语言程序设计,第八章 结构、联合、枚举,2019/7/12,3,内容提要,本章介绍3种用户自定义类型:结构、联合、枚举 需要掌握这几种用户自定义类型的以下知识: 为什么要定义这种类型,是为了适合何种数据存储与处理需要的 该类型定义的形式 该类型的变量在内存中占用空间的形式及其访问方式 重点是结构类型,对该类型还应掌握以下知识: 该类型的嵌套定义,其不同层次成员的访问方式 在结构中的同名问题 结构数组与结构指针的使用(处理一批记录) 结构类型在函数中的使用:形参的设定,返回值等问题 一些常用算法在结构中的实现(如排序),2019/7/12,4,结构类型定义,为什么需要结构类型: 有的时候需要一组相关的信息表示同一个对象,例如一个学生的信息包括:学号、姓名、性别、成绩等,这些数据项的类型不一定一致,即使是同一种类型也会对应不同的意义,因此需要将它们作为一个变量的成员组成一个整体。 此前所学的标准类型及数组和指针类型都无法满足这一需求 结构类型的定义格式: struct 结构类型名 结构体成员表列; ;,此关键字为定义结构类型的起始标志,结构类型名必须是用户自定义标识符,一对大括号必须有,其间是该结构体类型的各个成员,必须以分号结束,成员列表的形式: 成员类型名 成员名; 相同类型的成员名可以共用一个成员类型名,2019/7/12,5,结构类型定义,结构类型的定义举例: struct Date /表示日期的结构 int yr; /年 int mo; /月 int da; /日 ; struct Student /表示学生信息的结构 long unsigned id; /学号 double grades; /成绩 ;,int yr, mo, da; /年月日类型相同可用一个类型标识符,类型不一致的成员必须分别定义,2019/7/12,6,结构变量的定义,结构类型定义后, struct 结构类型名 就作为结构类型名使用,可以定义该类型的变量,有3种形式: (1)先定义结构类型,再定义结构变量 例:struct Date dt; struct Student st; (2)在定义结构类型的同时定义结构变量,结构类型名不省略,将结构变量名写在结构类型定义结束的右大括号之后、分号之前 例:struct Date /不省略结构类型名 int yr,mo,da; /年、月、日 dt; /定义结构变量dt,(3),结构类型名省略,结构类型名,2019/7/12,7,用typedef定义结构类型别名,用typedef可以为一个结构类型定义别名,以方便定义结构类型的变量,定义结构类型别名也有3种形式: (1)先定义结构类型,再定义结构类型的别名: 例:typedef struct Date Date; Date dt; (2)在定义结构类型的同时定义其别名 ,结构类型名不省略,将结构类型别名写在结构类型定义结束的右大括号之后、分号之前 例: typedef struct Date /不省略结构类型名 int yr,mo,da; /年、月、日 Date; /定义结构类型别名Date,(3),结构类型名省略,结构类型名,给已经定义的类型struct Date定义一个类型别名Date,直接用Date作为结构类型名定义一个结构变量dt,2019/7/12,8,结构变量的访问,结构变量的初始化:与其他类型的变量类似,结构变量在定义时也可以进行初始化,常用两种方式: (1)将初值用一对大括号括起,依次列出各个成员的值,所列出的值可以少于成员个数,默认用0填充 例:Date dt1=2005,8,16; Date dt2=2009,4; (2)两个类型一致的结构变量可以用一个为另一个初始化 例:Date dt4,dt3=dt1; 结构变量在定义之后,可进行赋值,满足以下要求: (1)两个类型一致的结构变量可以用一个为另一个赋值 (2)注意:结构变量定义之后,不能再用各个成员的值给结构变量作整体赋值,相当于: Date dt2=2009,4,0;,用dt1来初始化dt3,这里的dt4未初始化,例: dt4=dt1;,例: Date dt; dt=2005,8,16; X,2019/7/12,9,结构变量成员的访问,结构变量占用内存的方式: 与数组很类似,一个结构变量的各个成员在内存中依次占用地址相邻的内存单元,因此一个结构变量所占的空间至少为其各个成员所需的内存空间之和 结构变量与其成员的关系: 结构变量是一组(成员)变量的整体标志,是“外衣”,其中的每一个成员变量(简称成员)都是这个整体中的成分。 引用结构变量成员的方式: 必须从结构变量名开始,在其后加成员引用运算符“.”,再加成员名: 例: Date dt1=2005,8,16; 相当于:dt1.yr=2005; dt1.mo=8; dt1.da=16;,2019/7/12,10,结构变量成员的访问,程序8.1 结构变量成员的引用示例 该例中用到了前面例子中的两个结构体类型: struct Student /表示学生信息的结构 long unsigned id; /学号 float grades; /成绩 ; struct Date /表示日期的结构 int yr,mo,da; ;,2019/7/12,11,结构指针,结构指针的概念: 就是基类型为结构类型的指针,只能获得基类型一致的结构类型变量的地址. 结构指针的定义形式: 结构类型名 *结构指针变量名; 通过结构指针引用结构成员的两种等价方式: (1) (*结构指针). 结构成员 (2) 结构指针- 结构成员 例: Student s; Student *ps=,这里的Student是用typedef定义过的结构体类型别名,2019/7/12,12,结构数组,结构数组的概念: 就是基类型为结构类型的数组,因为数组类型并未规定其基类型必须是什么类型,事实上可以是任何类型 结构数组的定义形式: 结构类型名 结构数组名整型常量表达式; 通过结构数组引用结构成员的3种方式: (1)结构数组名下标.结构成员 (2)(*(结构数组名+下标).结构成员 (3) (结构数组名+下标)-结构成员 例: Student sa3; sai.id /第i+1个学生的学号 sai.grades /第i+1个学生的成绩,这里的Student是用typedef定义过的结构体类型别名,方式1,(*(sa+i).id (*(sa+i).grades,方式2,(sa+i)-id (sa+i)-grades,方式3,2019/7/12,13,结构数组,结构数组可以初始化,方法是: 每个数组元素的各个分量用第二层括号的括起。 例:Student sa3= 1001,80,1002,89,1003,90; 结构数组在内存中的存放方式: 占用一组地址连续的空间,数组元素相邻,元素的各成员相邻,1001,80,1002,89,1003,90,sa0.id,sa0.grades,sa1.id,sa1.grades,sa2.id,sa2.grades,程序8.2从键盘上输入3个学生记录,并在屏幕输出,(请在VC+下运行),2019/7/12,14,结构的嵌套,结构嵌套的概念: 结构的成员可以是任何类型,当然也可以是结构类型,这样就形成了结构的嵌套 结构嵌套的定义形式: (1)先定义”小”的结构类型,再在”大”的结构类型中用其作为某成中类型名 (2)将小结构类型的定义嵌套在大的结构类型定义中 例: struct Date int yr,mo,da; ; typedef struct Date Date;,struct Student long unsigned id; double grades; Date dt; /入学日期dt ; typedef struct Student Student;,方式1,方式2,2019/7/12,15,结构的嵌套,程序8.3:用结构嵌套定义一个学生结构,从键盘上输入3个学生记录,并在屏幕输出。 主函数输入部分主要代码:(输出的代码类似) int i; Student sa3; printf(“Enter 3 records:n“); for(i=0;i3;i+) /输入3个学生的各项信息 scanf(“%Lu%Lf“, ,2019/7/12,16,结构型返回值和地址调用,结构类型也可以作为返回类型 根据第6章有返回值的函数调用过程中经过3次赋值的知识,结构类型作为函数返回类型显然是低效的 结构变量由很多成员组成,一般占用空间较大 这就意味着临时变量的空间较大,赋值也需要时间 因此一般将返回值类型改为void型,而增设一个结构类型的指针形参,通过间接引用修改对应实参结构体变量的值。 下面的动态演示展示了二者的区别与效率差异 本例再一次体现出指针的高效性,2019/7/12,17,结构应用举例-学生记录排序,分析:一组学生记录,首先要定义一维数组, 该数组的元素类型为结构类型,因此本题需定义一维结构数组 排序算法:第6章所学的排序算法在这里都可以使用,只是在元素互相交换时,体现为结构体变量的交换 函数参数的选择:由第6章的知识,本题形参用一级指针最高效,指针的基类型就是一维数组的基类型 模块的划分:定义一个输入函数、排序函数、输出函数,主函数定义一维结构数组作为实参,依次调用这3个函数完成整个程序 结构类型:本例的结构类型就是前面一直介绍的Student类型,包括学号和成绩两个域,2019/7/12,18,结构应用举例-学生记录排序,读入部分:见动态演示 排序算法: void SelectSort(Student* pa,int n) /选择排序 int i,j,min; Student temp; /定义结构临时变量 for(i=0;in-1;i+) /控制n-1趟循环 min=i; /用min记下本趟分数最小元素的下标 for(j=i+1;jn;j+) if(paj.gradespamin.grades) min=j; if(min!=i) /如果分数最小元素未到位,交换元素 temp=pai; pai=pamin; pamin=temp; ,完整程序请上机运行,2019/7/12,19,结构应用举例-洗牌,程序8.5 洗牌程序。假设洗牌之前52张扑克牌按照红桃、方块、梅花和黑桃四种花色的顺序,每种花色又是按照从1到13的顺序排列。通过产生随机数模拟洗牌,每一张牌与随机选定的一张牌调换,从而打乱最初的次序。 问题分析: (1)每张扑克牌用哪些信息可以完整表示-花色+点数 结构类型的定义: struct Card char suit; /记录花色 int pips; /记录点数 ; typedef struct Card Card;,2019/7/12,20,结构应用举例-洗牌,(2)所有扑克牌信息的存储需要用一维结构数组 结构数组的定义: Card deck52; (3)初始信息的表示:52张牌最初按红桃、方块、梅花和黑桃四种花色的顺序,每种花色又按照从1到13的顺序排列 for(i=0;i52;i+) decki.suit=i/13+3; /赋花色的ASCII码 decki.pips=i%13+1; /赋每张牌的点数 (4)关键的步骤,如何实现模拟洗牌? 编写洗牌函数Shuffle(struct Card *p,int n)。通过一个循环,每一张牌与随机选定的一张牌调换。,红桃、方块、梅花和黑桃的ASCII码分别是3、4、5和6,调用随机函数产生051之间的随机数作为第几张牌序号,2019/7/12,21,结构应用举例-洗牌,(2)所有扑克牌信息的存储需要用一维结构数组 结构数组的定义: Card deck52; (3)初始信息的表示:52张牌最初按红桃、方块、梅花和黑桃四种花色的顺序,每种花色又按照从1到13的顺序排列 for(i=0;i52;i+) decki.suit=i/13+3; /赋花色的ASCII码 decki.pips=i%13+1; /赋每张牌的点数 (4)关键的步骤,如何实现模拟洗牌? 编写洗牌函数Shuffle(struct Card *p,int n)。通过一个循环,每一张牌与随机选定的一张牌调换。,红桃、方块、梅花和黑桃的ASCII码分别是3、4、5和6,调用随机函数产生051之间的随机数作为第几张牌序号,2019/7/12,22,结构应用举例-洗牌,洗牌函数: void Shuffle(Card *pa,int n) int i,j; struct Card temp; srand(time(0); /使随机函数值随时间变化 for(i=0;in;i+) j=rand()%n; /随机选择一张牌与当前牌i调换 temp=pai; /与当前牌调换 pai=paj; paj=temp; ,完整程序请上机运行,2019/7/12,23,联合类型定义,为什么需要联合类型: 有如果一组数据分别属于不同的类型,而每次处理仅访问其中一种类型的数据,那么为了节省存储资源,这组数据可以共享一段空间,这就需要定义联合类型的变量。 联合类型的定义格式: union 联合类型名 联合中的成员表列; ; 联合类型变量的定义方式与结构一样,也有3种: 先定义类型后定义变量、定义类型的同时定义变量(类型名不缺省和缺省都可以),此关键字为定义联合类型的起始标志,联合类型名必须是用户自定义标识符,一对大括号必须有,其间是该联合类型的各个成员,必须以分号结束,成员列表的形式: 成员类型名 成员名; 相同类型的成员名可以共用一个成员类型名,2019/7/12,24,联合类型及变量的定义,联合类型及变量的定义举例: union UNI /定义联合类型 char ch; float x; ; typedef union UNI UNI; /定义类型别名 UNI u; /定义联合类型变量 联合变量的成员占用内存方式: 联合变量的成员共享空间,变量所占内存的大小等于其最大的1个成员空间大小-空间共享 联合空间只有一个最新赋的成员值有效,后来的值覆盖前面 的值-后来为主,2019/7/12,25,联合变量的访问,联合变量的初始化:与其他类型的变量类似,联合变量在定义时也可初始化,但只能初始化第一个成员 UNI u=A; /合法 UNI u=A,3.14; /非法 UNI u=3.14; /告警,将3.14转化为字符型时信息丢失 不能对联合变量整体赋值、只能对成员实施读、写或运算“=” 对成员也用点运算符,方式同结构成员的访问,例: u.x=3.1415F; /合法 u=3.1415F; /非法 u.ch=B; /合法 u=B; /非法,2019/7/12,26,联合应用举例,程序8.6 联合类型的定义及使用简单示例(主函数) . int main( ) UNI u; printf(“Input a real number:“); scanf(“%f“, ,2019/7/12,27,联合与结构,两种类型最本质的区别:结构变量的所有成员在内存中依次占用空间,所需空间至少为各成员空间大小之和;而联合变量的所有成员共享一段内存空间,所需空间为占空间最大的成员所需空间 访问联合成员的方式与访问结构成员的方式完全相同 对联合变量的其中一个成员读入或赋值以后,可以访问其它成员,但显示结果是将在内存中01序列解释为所访问成员类型的值。 联合数组、联合指针的意义与结构数组、结构指针类似 随着硬件技术的提高,已不必通过定义联合类型节省内存空间,因此联合类型在编程时用得并不广泛,2019/7/12,28,枚举类型及变量的定义,为什么需要枚举类型: 有时候解决问题,为了用直观形象的标识符来表示一个类型中的有限个常量值,需要定义枚举类型。 例如:一年四季用Spring、Summer、Autumn、Winter比直接用1、2、3、4更加直观。 枚举类型的定义格式: enum 枚举类型名枚举常量1,枚举常量2,枚举常量n; 例:enum WEEKDAYsun,mon,tue,wed,thu,fri,sat; 枚举变量的定义方式: 与结构体变量一样,也有3种方式,不再赘述,此关键字为定义枚举类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年特岗教师招聘考试初中生物模拟题及答案
- 2025年网络安全工程师职位面试预测题与解析
- 【教案版】小学二班级上册 轮滑
- 2025年炼油装置中级操作工面试技巧与模拟试题
- 2025年教育培训专员面试技巧与模拟题集
- 2025年中级会计师职称考试试题集与解析
- 2025年权威资料特岗教师招聘初中地理全真模拟题及答案收录
- 2025年生物科技行业招聘面试预测题集萃
- 2025年烷基化工艺作业面试常见问题解答
- 2025年电气工程师初级面试预测题及专业知识点梳理
- 2024至2030年中国苯甲酰氯行业发展状况及投资规划研究报告
- 1.1 鸦片战争 课件 2024-2025学年统编版八年级历史上册
- 2024至2030年中国演播室行业市场调查研究及发展战略规划报告
- DB11∕T 420-2019 电梯安装、改造、重大修理和维护保养自检规则
- 国旗台施工合同
- 总代理授权书
- 越剧《梁山伯与祝英台》剧本
- 广东省广州市越秀区2024年八年级下学期期末英语试卷附答案
- 医疗器械售后服务能力证明资料模板
- (正式版)JBT 14449-2024 起重机械焊接工艺评定
- (正式版)HGT 4144-2024 工业用二正丁胺
评论
0/150
提交评论