C语言程序设计课件第8章-结构、联合、枚举_第1页
C语言程序设计课件第8章-结构、联合、枚举_第2页
C语言程序设计课件第8章-结构、联合、枚举_第3页
C语言程序设计课件第8章-结构、联合、枚举_第4页
C语言程序设计课件第8章-结构、联合、枚举_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言程序设计

2024/5/131第八章结构、联合、枚举主讲:计算机学院内容提要本章介绍3种用户自定义类型:结构、联合、枚举需要掌握这几种用户自定义类型的以下知识:为什么要定义这种类型,是为了适合何种数据存储与处理需要的该类型定义的形式该类型的变量在内存中占用空间的形式及其访问方式重点是结构类型,对该类型还应掌握以下知识:该类型的嵌套定义,其不同层次成员的访问方式在结构中的同名问题结构数组与结构指针的使用(处理一批记录)结构类型在函数中的使用:形参的设定,返回值等问题一些常用算法在结构中的实现(如排序)2024/5/133结构——类型定义为什么需要结构类型:有的时候需要一组相关的信息表示同一个对象,例如一个学生的信息包括:学号、姓名、性别、成绩等,这些数据项的类型不一定一致,即使是同一种类型也会对应不同的意义,因此需要将它们作为一个变量的成员组成一个整体。此前所学的标准类型及数组和指针类型都无法满足这一需求结构类型的定义格式:struct

结构类型名{ 结构体成员表列;};此关键字为定义结构类型的起始标志结构类型名必须是用户自定义标识符一对大括号必须有,其间是该结构体类型的各个成员必须以分号结束成员列表的形式:成员类型名成员名;相同类型的成员名可以共用一个成员类型名2024/5/134结构——类型定义结构类型的定义举例:structDate //表示日期的结构{

intyr;//年

intmo;//月

int

da;//日};structStudent//表示学生信息的结构{longunsignedid;//学号doublegrades; //成绩};intyr,mo,da;

//年月日类型相同可用一个类型标识符类型不一致的成员必须分别定义2024/5/135结构变量的定义结构类型定义后,struct

结构类型名就作为结构类型名使用,可以定义该类型的变量,有3种形式:(1)先定义结构类型,再定义结构变量例:structDatedt;

structStudentst; (2)在定义结构类型的同时定义结构变量,结构类型名不省略,将结构变量名写在结构类型定义结束的右大括号之后、分号之前例:structDate //不省略结构类型名{

int

yr,mo,da;//年、月、日}dt;//定义结构变量dt(3)结构类型名省略结构类型名2024/5/136用typedef定义结构类型别名用typedef可以为一个结构类型定义别名,以方便定义结构类型的变量,定义结构类型别名也有3种形式:(1)先定义结构类型,再定义结构类型的别名:例:typedef

structDateDate;

Date

dt; (2)在定义结构类型的同时定义其别名,结构类型名不省略,将结构类型别名写在结构类型定义结束的右大括号之后、分号之前例:typedef

structDate //不省略结构类型名{

int

yr,mo,da;//年、月、日}Date;//定义结构类型别名Date(3)结构类型名省略结构类型名给已经定义的类型structDate定义一个类型别名Date

直接用Date作为结构类型名定义一个结构变量dt2024/5/137结构变量的访问结构变量的初始化:与其他类型的变量类似,结构变量在定义时也可以进行初始化,常用两种方式:(1)将初值用一对大括号括起,依次列出各个成员的值,所列出的值可以少于成员个数,默认用0填充例:Datedt1={2005,8,16};Datedt2={2009,4};(2)两个类型一致的结构变量可以用一个为另一个初始化例:Datedt4,dt3=dt1;

结构变量在定义之后,可进行赋值,满足以下要求:(1)两个类型一致的结构变量可以用一个为另一个赋值(2)注意:结构变量定义之后,不能再用各个成员的值给结构变量作整体赋值相当于:

Datedt2={2009,4,0};用dt1来初始化dt3,这里的dt4未初始化例:dt4=dt1;例:

Datedt;dt={2005,8,16};X

2024/5/138结构变量成员的访问结构变量占用内存的方式:与数组很类似,一个结构变量的各个成员在内存中依次占用地址相邻的内存单元,因此一个结构变量所占的空间至少为其各个成员所需的内存空间之和结构变量与其成员的关系:结构变量是一组(成员)变量的整体标志,是“外衣”,其中的每一个成员变量(简称成员)都是这个整体中的成分。引用结构变量成员的方式:必须从结构变量名开始,在其后加成员引用运算符“.”,再加成员名:例:Datedt1={2005,8,16};相当于:dt1.yr=2005;dt1.mo=8;dt1.da=16;2024/5/139结构变量成员的访问程序8.1结构变量成员的引用示例该例中用到了前面例子中的两个结构体类型:structStudent//表示学生信息的结构{longunsignedid;//学号floatgrades; //成绩};structDate //表示日期的结构{

int

yr,mo,da;};动态演示过程2024/5/1310结构指针结构指针的概念:就是基类型为结构类型的指针,只能获得基类型一致的结构类型变量的地址.结构指针的定义形式:结构类型名*结构指针变量名;通过结构指针引用结构成员的两种等价方式:(1)

(*结构指针).结构成员(2)结构指针->结构成员例:

Students;

Student*ps=&s; //指向结构s的指针ps

ps->id=2005065; //相当于(*ps).id=2005065;ps->grades=90.5; //相当于(*ps).grades=90.5;这里的Student是用typedef定义过的结构体类型别名2024/5/1311结构数组结构数组的概念:就是基类型为结构类型的数组,因为数组类型并未规定其基类型必须是什么类型,事实上可以是任何类型结构数组的定义形式:结构类型名

结构数组名;通过结构数组引用结构成员的3种方式:(1)结构数组名[下标].结构成员(2)(*(结构数组名+下标)).结构成员(3)(结构数组名+下标)->结构成员例: Studentsa[3];

sa[i].id //第i+1个学生的学号

sa[i].grades //第i+1个学生的成绩这里的Student是用typedef定义过的结构体类型别名方式1(*(sa+i)).id(*(sa+i)).grades

方式2(sa+i)->id(sa+i)->grades

方式32024/5/1312结构数组结构数组可以初始化,方法是:每个数组元素的各个分量用第二层括号的括起。例:Studentsa[3]={{1001,80},{1002,89},{1003,90}};

结构数组在内存中的存放方式:占用一组地址连续的空间,数组元素相邻,元素的各成员相邻100180100289100390sa[0].idsa[0].gradessa[1].idsa[1].gradessa[2].idsa[2].grades程序8.2从键盘上输入3个学生记录,并在屏幕输出动态演示过程(请在VC++下运行)2024/5/1313结构的嵌套结构嵌套的概念:结构的成员可以是任何类型,当然也可以是结构类型,这样就形成了结构的嵌套结构嵌套的定义形式:(1)先定义”小”的结构类型,再在”大”的结构类型中用其作为某成中类型名(2)将小结构类型的定义嵌套在大的结构类型定义中例:

structDate {

int

yr,mo,da;};

typedef

structDateDate;

structStudent {longunsignedid;doublegrades;

Datedt;//入学日期dt

};

typedef

structStudent

Student;

方式1

structDate {

int

yr,mo,da;}dt;方式22024/5/1314结构的嵌套程序8.3:用结构嵌套定义一个学生结构,从键盘上输入3个学生记录,并在屏幕输出。主函数输入部分主要代码:(输出的代码类似)inti;Studentsa[3];printf("Enter3records:\n");for(i=0;i<3;i++)//输入3个学生的各项信息{

scanf("%Lu%Lf",&sa[i].id,&sa[i].grades);

scanf("%d/%d/%d",&sa[i].dt.yr,&sa[i].dt.mo,&sa[i].dt.da);}动态演示过程2024/5/1315结构型返回值和地址调用

结构类型也可以作为返回类型根据第6章有返回值的函数调用过程中经过3次赋值的知识,结构类型作为函数返回类型显然是低效的结构变量由很多成员组成,一般占用空间较大这就意味着临时变量的空间较大,赋值也需要时间因此一般将返回值类型改为void型,而增设一个结构类型的指针形参,通过间接引用修改对应实参结构体变量的值。下面的动态演示展示了二者的区别与效率差异本例再一次体现出指针的高效性动态演示过程2024/5/1316结构应用举例---学生记录排序分析:一组学生记录,首先要定义一维数组,该数组的元素类型为结构类型,因此本题需定义一维结构数组排序算法:第6章所学的排序算法在这里都可以使用,只是在元素互相交换时,体现为结构体变量的交换函数参数的选择:由第6章的知识,本题形参用一级指针最高效,指针的基类型就是一维数组的基类型模块的划分:定义一个输入函数、排序函数、输出函数,主函数定义一维结构数组作为实参,依次调用这3个函数完成整个程序结构类型:本例的结构类型就是前面一直介绍的Student类型,包括学号和成绩两个域2024/5/1317结构应用举例---学生记录排序读入部分:见动态演示排序算法:voidSelectSort(Student*pa,intn)//选择排序{

int

i,j,min; Studenttemp;//定义结构临时变量

for(i=0;i<n-1;i++) //控制n-1趟循环

{ min=i; //用min记下本趟分数最小元素的下标

for(j=i+1;j<n;j++)

if(pa[j].grades<pa[min].grades)min=j;

if(min!=i)//如果分数最小元素未到位,交换元素

{temp=pa[i];

pa[i]=pa[min];

pa[min]=temp; } }}动态演示过程完整程序请上机运行2024/5/1318结构应用举例---洗牌程序8.5

洗牌程序。假设洗牌之前52张扑克牌按照红桃、方块、梅花和黑桃四种花色的顺序,每种花色又是按照从1到13的顺序排列。通过产生随机数模拟洗牌,每一张牌与随机选定的一张牌调换,从而打乱最初的次序。问题分析:(1)每张扑克牌用哪些信息可以完整表示---花色+点数结构类型的定义:structCard{ charsuit; //记录花色

intpips; //记录点数};typedef

structCardCard;2024/5/1319结构应用举例---洗牌(2)所有扑克牌信息的存储需要用一维结构数组结构数组的定义:Carddeck[52];(3)初始信息的表示:52张牌最初按红桃、方块、梅花和黑桃四种花色的顺序,每种花色又按照从1到13的顺序排列for(i=0;i<52;i++){

deck[i].suit=i/13+3;//赋花色的ASCII码

deck[i].pips=i%13+1;//赋每张牌的点数}(4)关键的步骤,如何实现模拟洗牌?编写洗牌函数Shuffle(structCard*p,intn)。通过一个循环,每一张牌与随机选定的一张牌调换。红桃、方块、梅花和黑桃的ASCII码分别是3、4、5和6调用随机函数产生0~51之间的随机数作为第几张牌序号2024/5/1320结构应用举例---洗牌(2)所有扑克牌信息的存储需要用一维结构数组结构数组的定义:Carddeck[52];(3)初始信息的表示:52张牌最初按红桃、方块、梅花和黑桃四种花色的顺序,每种花色又按照从1到13的顺序排列for(i=0;i<52;i++){

deck[i].suit=i/13+3;//赋花色的ASCII码

deck[i].pips=i%13+1;//赋每张牌的点数}(4)关键的步骤,如何实现模拟洗牌?编写洗牌函数Shuffle(structCard*p,intn)。通过一个循环,每一张牌与随机选定的一张牌调换。红桃、方块、梅花和黑桃的ASCII码分别是3、4、5和6调用随机函数产生0~51之间的随机数作为第几张牌序号2024/5/1321结构应用举例---洗牌洗牌函数:voidShuffle(Card*pa,intn){

int

i,j; structCardtemp;srand(time(0)); //使随机函数值随时间变化

for(i=0;i<n;i++)

{ j=rand()%n;//随机选择一张牌与当前牌i调换

temp=pa[i];//与当前牌调换

pa[i]=pa[j];

pa[j]=temp;

}}动态演示过程完整程序请上机运行2024/5/1322联合——类型定义为什么需要联合类型:有如果一组数据分别属于不同的类型,而每次处理仅访问其中一种类型的数据,那么为了节省存储资源,这组数据可以共享一段空间,这就需要定义联合类型的变量。联合类型的定义格式:union联合类型名{ 联合中的成员表列;};联合类型变量的定义方式与结构一样,也有3种:先定义类型后定义变量、定义类型的同时定义变量(类型名不缺省和缺省都可以)此关键字为定义联合类型的起始标志联合类型名必须是用户自定义标识符一对大括号必须有,其间是该联合类型的各个成员必须以分号结束成员列表的形式:成员类型名成员名;相同类型的成员名可以共用一个成员类型名2024/5/1323联合——类型及变量的定义联合类型及变量的定义举例:unionUNI //定义联合类型{charch;floatx;};typedefunionUNIUNI;//定义类型别名UNIu; //定义联合类型变量联合变量的成员占用内存方式:联合变量的成员共享空间,变量所占内存的大小等于其最大的1个成员空间大小----空间共享联合空间只有一个最新赋的成员值有效,后来的值覆盖前面的值----后来为主u.x(占4字节)u.ch(占1字节)2024/5/1324联合变量的访问联合变量的初始化:与其他类型的变量类似,联合变量在定义时也可初始化,但只能初始化第一个成员UNIu={'A'}; //合法UNIu={'A',3.14}; //非法UNIu={3.14}; //告警,将3.14转化为字符型时信息丢失不能对联合变量整体赋值、只能对成员实施读、写或运算“=”对成员也用点运算符,方式同结构成员的访问,例:u.x=3.1415F;

//合法u={3.1415F}; //非法u.ch='B';//合法u={'B'}; //非法2024/5/1325联合应用举例程序8.6

联合类型的定义及使用简单示例(主函数)...............................intmain(){UNIu; printf("Inputarealnumber:");

scanf("%f",&u.x); printf(“u.ch=%c,u.x=%f\n”,u.ch,u.x);

getchar();//跳过回车符

printf("Inputacharacter:");

scanf("%c",&u.ch); printf("u.ch=%c,u.x=%f\n",u.ch,u.x);

return0;}动态演示过程2024/5/1326联合与结构两种类型最本质的区别:结构变量的所有成员在内存中依次占用空间,所需空间至少为各成员空间大小之和;而联合变量的所有成员共享一段内存空间,所需空间为占空间最大的成员所需空间访问联合成员的方式与访问结构成员的方式完全相同对联合变量的其中一个成员读入或赋值以后,可以访问其它成员,但显示结果是将在内存中01序列解释为所访问成员类型的值。

联合数组、联合指针的意义与结构数组、结构指针类似随着硬件技术的提高,已不必通过定义联合类型节省内存空间,因此联合类型在编程时用得并不广泛2024/5/1327枚举——类型及变量的定义为什么需要枚举类型:有时候解决问题,为了用直观形象的标识符来表示一个类型中的有限个常量值,需要定义枚举类型。例如:一年四季用Spring、Summer、Autumn、Winter比直接用1、2、3、4更加直观。枚举类型的定义格式:e

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论