欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载
     

    第14章结构体、共用体、枚举和typedef.ppt

    • 资源ID:2251137       资源大小:247.01KB        全文页数:32页
    • 资源格式: PPT        下载积分:6
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要6
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    第14章结构体、共用体、枚举和typedef.ppt

    第14章 结构体、共用体、枚举和typedef,程序设计中,如何合理组织数据是门大学问,前面介绍过的数组是种组织数据的方式,但数组只适用于同类型的数据,如果类型不同又当如何?而且,现实中,很多东西都具有不同的属性,以人为例,像姓名、性别、身高等等都是其属性,如何合理存储并方便地访问这些信息,是本章介绍的内容。,14.1 什么是结构体,仍以人为例来介绍,要管理姓名、单位、Email地址、联系电话等信息,现实生活中,很多人采用名片的形式,将这些信息印在一张卡片上。收集的一张张名片大大方便了数据的管理,将这种理念借鉴到C语言程序设计中,是否有类似于名片的那么一种变量呢? 有,答案就是“结构体变量”,是一种复合变量,在进一步说明结构体变量前,先来看“结构体”的概念,结构体和结构体变量的关系类似与类型与普通变量的关系,结构体中说明了结构体变量的信息格式,而结构体变量是结构体的实例。,14.1.1 结构体的定义,只有定义了一个结构体,才能声明并使用结构体变量,正如,只有确定了名片上要印什么内容,才能开始印刷名片。结构体的定义就是说明结构体变量要存储什么信息的过程。 C语言提供了关键字struct来定义一个结构,一般形式的结构定义为: struct 结构名称(或称标识) 存储数据列表;(或称成员变量列表) ; 注意:在定义结构时,一定不要忘记花括号后的分号,因为结构的定义可以看成一条完整的C+语句,否则编译器会报错。 举例来说, struct person char name20; int age; char email50; ;,14.1.2 声明结构体变量,以上面person结构为例,定义完毕后,person就可以看成是一种类型,可以通过下述形式声明结构体变量zangsan: struct person zangsan; 注意区分person和zangsan,person只是结构体定义,是种规范说明,编译器并不为其分配内存空间,而zangsan是实实在在的结构体变量,占据一定的内存空间。 在定义结构体的同时也可以完成一个或多个结构体变量的声明,举例来说: struct person char name20; int age; char email50; zangsan,lisi,wangwu,*zaoliu; 上述代码在定义结构体person的同时,一口气声明了3个结构体变量:zangsan,lisi,wangwu,甚至还声明了一个指向person结构的指针zaoliu。,14.1.3 初始化结构变量,在声明结构变量的同时,可以进行变量的初始化,对结构体中每个数据初始化,用逗号隔开,并用花括号包裹起来,举例来看: struct person zangsan=“Zang San”, 24, “zs163.com”; 还可以将结构体定义,结构体变量声明和初始化放在一起来完成,如: struct person char name20; int age; char email50; zangsan=“Zang San”, 24, “zs163.com”, *pzs=,14.1.4 访问结构体成员,习惯上将诸如字符串name、int变量age和字符串email等称为结构体person及其声明变量的“数据成员”,简称“成员”。 声明了一个结构体变量后,可以使用成员操作符(.)来访问各个成员(内部存储的数据),如zangsan.name,zangsan.age和zangsan.emal分别代表zangsan这个变量(结构体变量)中存储的姓名、年龄和email等信息,来看一段示例: 代码 访问结构体变量中的数据成员StructSample,14.1.5 结构体定义的位置,读者可以做个有趣的尝试:将中结构体定义的部分转移到main函数的后面,重新编译运行,会发生什么? 编译器会报一大堆的错误,正如“使用变量前必须先对其声明”一样,在使用结构体类型声明结构体变量之前,必须要先进行结构体的定义,编译器据此才知道如何为结构体中的数据成员分配内存空间,才能声明结构体变量。 除了如的定义方式外,结构体还可以定义在函数(包括main函数)中,两种定义方式的区别在于结构体可见域不同,如果定义在函数外,从定义处到本文件结束,结构体都可见,可用结构体声明结构体变量,但如果定义在特定函数中,只有定义处到该函数结束,结构体可见,如果在函数外使用结构体声明结构体变量,可能会引发错误。 一种推荐的写法是将结构体定义在头文件中,只要某文件A包含了此头文件,便可在A中自由声明结构体变量。,14.1.6 结构体变量赋值,C语言不允许使用一个数组直接为另一个数组赋值,但使用一个结构体变量为另一个结构体变量赋值是合法的,可以使用赋值操作符(=)将一个结构变量B赋值给另一个结构变量A,这样,结构变量A中的每个成员都将被设置成结构变量B中相应成员的值,即使成员是数组类型也不例外,这种赋值方式被成为成员赋值,见示:,14.2 特殊结构体,上一节中讨论的person结构相对简单,只包含了3个数据成员:name、age和email,如果面对的是更为复杂的结构,将所有的数据成员并排似乎不是个高效的方法,那能否使用结构体嵌套,一层层管理数据呢?,14.2.1 结构体嵌套,顾名思义,结构体嵌套就是“结构体套结构体”,某个结构的数据成员也是一个结构体变量,这样,可以按层次结构合理组织数据,举例来说: struct student char name20; struct scorestruct /*结构体scorestruct的定义*/ int math; int English; score; /*声明结构体变量score*/ struct infostruct /*结构体infostruct的定义*/ float height; float weight; info; /*声明结构体变量info*/ ;,14.2.2 匿名结构体,C语言允许定义匿名结构,所谓匿名结构,就是不指定结构体的名称,但一定要在结构体定义的同时声明至少一个结构体变量,否则,这种用法没有意义,如: struct char name20; int age; wangwu, lisi; 这样便声明创建了两个结构体变量wangwu和lisi,可以通过诸如“wangwu.name”等形式来访问其成员,但这种类型没有名称,因此无法在以后的程序中声明这种类型的变量。,14.3 共用体,共用体也是一种特殊的数据组织方式,C语言使用关键字union来定义一个共用体结构,所以,在某些书籍中也将共用体称为“联合”。和结构体类似,共用体的使用也分为“共用体的定义”、“共用体变量的声明、初始化和使用”两大部分。,14.3.1 什么是共用体,和结构一样,共用体也是由数据成员组成的,但在结构中,编译器为每个数据成员都分配内存地址空间,但对共用体来说,所有的数据成员共用一块内存,这个“共用”似乎有些费解,理解方式应当是“在某个确定的时刻,共用体只能表示一种成员类型”。,14.3.2 共用体的定义,共用体可采用如下形式定义: union 共用体名称(或称标识) 存储数据列表(或称成员变量列表) ; 注意,结束花括号后的分号(;)不要遗漏,这种定义形式是一个完整的C+语句。 举例来说: union computerInfo /*定义一个共用体computerInfo*/ char typeid20; float price; ; 某个部门要登记所有的电脑,如果是品牌机,就登记型号(typeid),如果是组装机,就登记价格(price),因此,型号和价格只取其一,这时使用共用体最为合适。,14.3.3 声明共用体变量,和结构体的使用方式一样,定义了共用体后,共用体名可以看成是一种类型,用其可声明共用体变量,基本格式为: union 共用体名 共用体变量; 在定义共用体的同时也可以完成一个或多个共用体变量的声明,举例来说: union computerInfo /*定义一个共用体computerInfo*/ char typeid20; float price; comp1, comp2;,14.3.4 共用体变量的初始化,在声明一个共用体比昂两的同时,可以完成其初始化,与结构变量的初始化不同的是,只能对共用体变量列表中的一个变量进行初始化,对前面定义的共用体computerInfo来说,下列语句是合法的: computerInfo com1=“Asus X80“; computerInfo com1=6000; 与结构类似,可以把共用体定义、共用体变量声明及其初始化放在一起,如: union computerInfo /*定义一个共用体computerInfo*/ char typeid20; float price; comp1=“ Asus X80“;,14.3.5 共用体成员访问,不论共用体在定义时成员列表中有多少项,在某个确定时刻,共用体变量只能存储一个成员,来看一个示例:,14.3.6 共用体赋值,从本质上理解,共用体实际上是为不同的成员分配一块共用内存,编译器并不会约束存入这块内存的值,关键在于程序员如何解析这块内存,如何使用存入的内容。 C语言允许共用体变量间的赋值,且无论是结构体变量的赋值还是共用体变量的赋值,实际上都是内存单元的照搬复制。,14.4 结构体和共用体的内存差异,结构体变量和共用体变量是两种复合类型的变量,对C语言内置的基本数据类型,我们都明确知道其占用的内存空间大小,但结构体变量和共用体变量占据多大的内存空间呢?两种变量在内存中的表示形式有何差别?这是本节讨论的问题。,14.4.1 结构体变量和共用体变量内存形式的不同,前面以及提到,编译器会为结构体变量中的每个数据成员分配不同的地址空间,也就是说,结构体变量中的数据程序是并列关系,而编译器为共用体变量中的数据成员分配的是同一块内存,每个时刻只有一个数据成员有意义,从地址的角度来看两者的差异,形象地表明了这一点。,14.4.2 结构体变量的内存大小,直观上理解,结构体变量占据的内存单元的个数应当是其内部所有数据成员占据内存单元数的和,但实际情况却并非如此,来看一段:,14.4.3 字节对齐,出于效率的考虑,C语言引入了字节对齐机制,一般来说,不同的编译器字节对齐机制有所不同,但还是有以下3条通用准则: (1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除; (2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); (3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。,14.4.4 最宽基本类型,字节对齐第3条准则提及最宽基本类型的概念,所谓基本类型是指像char、short、int、float、double这样的内置数据类型。“数据宽度”就是指其sizeof的大小。诸如结构体、共用体和数组等都不是基本数据类型,来看一段示例:,14.4.5 共用体的大小,原则上,共用体的大小取决于占据最多内存的成员的长度,如: union Example char c; short s; float f; ; 则sizeof(Example)的结果为4,但字节对齐准则3,“结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)”仍然成立,来看下面的共用体定义: union Example char c9; double d; ;,14.5 枚举类型,从字面上理解,枚举是“列举所有情况”的意思,C语言中,枚举类型也是这么用的,枚举类型是种用户自定义的类型,在定义枚举类型时,需指明其取值集合,用枚举类型声明枚举变量时,只能取集合中的某项作为其值,这在一定程度上保证了取值的安全性。,14.5.1 枚举类型的定义,C语言提供了关键字Enum定义枚举类型,基本格式为: enum 枚举类型名 枚举常量1=整型常数,枚举常量2=整型常数,; 作为一条完整的C语句,不要忘记结尾的分号。 枚举类型的定义包括以下要素: 枚举类型名,有效的C语言标识符。 枚举表,即“枚举常量1=整型常数,枚举常量2=整型常数,”部分,枚举表是枚举常量的集合,枚举表中每项后的“=整型常数”是给枚举常量赋初值,方括号代表赋初值的操作可以省略。 如果不给枚举常量赋初值,编译器会为每一个枚举常量赋一个不同的整型值,第一个为0,第二个为1,等等。当枚举表中某个常量赋值后,其后的成员则按依次加1的规则确定其值。 来看一个简单的例子: enum day Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;,14.5.2 声明枚举变量,定义了枚举类型day后,便可声明day型枚举变量,如: enum day today; 上述语句声明了day型变量today。注意,today只能取枚举表中的某项作为其值,枚举变量在其枚举表成员之外取值是不允许的。 可在枚举类型定义的同时声明该类型的变量,如: enum day Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday toay;,14.5.3 枚举常量是什么,在上面定义的枚举类型day中,诸如Monday、Tuesday等称为枚举常量,有个疑问:枚举常量到底是什么?来看一段示例: 代码 枚举常量EnumConst #include /*使用printf要包含的头文件*/ #include enum color Red,Green,Blue,Black,White; /*枚举类型的定义*/ void main(void) /*主函数*/ enum color c1=Blue; printf(“Blue is %d“,c1); /*枚举常量是整型*/ getch(); /*等待,按任意键继续*/ 输出结果为 Blue is 2,14.6 给类型取个别名typedef,可以给某个已经存在的类型取个别名,使其更易写、更易记,C语言中提供了两种方法,一是使用“#define”语句,另一个方法是使用typedef语句,两者之间存在细微的差别。,14.6.1 typedef基本用法,先来看一个直观的例子: typedef double* DP; typedef为double* 引入了一个新的助记符DP,在程序中可使用DP声明一个指向double型变量的指针,如: DP pDouble1, pDouble2; 上述代码声明了两个double型的指针变量pDouble1和pDouble2。,14.6.2 #define用法,#define语句称为预定义语句,是预处理指令,在编译预处理时进行简单的替换,不做正确性检查,不管含义是否正确,只是简单的替换,如: #define DP double* 程序中,所有出现DP的地方都被替换为double*,再来看下述语句: DP pDouble1, pDouble2; 编译预处理时将被替换为: double* pDouble1, pDouble2; 上述语句声明了一个double型指针变量pDouble1和一个double型变量pDouble2。由此,读者可体会typedef和#define的差别。 typedef语句后的分号不要忘记,define不是语句,后面不能加分号,如果define结构后出现分号,会一起被替换。,14.7 小结,本章讨论了几种重要的数据类型组织方式,主要有结构体、共用体和枚举类型,结构体相当于是对成员类型打包,而共用体在某个时刻只有一个成员有意义,枚举类型限定了变量的取值范围,在某些场合有独特的应用。 3种类型的使用方式基本一致,都是要先完成类型的定义,才能声明、初始化和使用该类型的变量。对结构体和共用体来说,通过数据成员访问符“.”可有效访问变量的成员。 理论上,结构体变量的大小应等于所有成员占据内存大小的和,而共用体变量的大小取决于占内存最大的成员,但出于访问效率的考虑,C语言引入了字节对齐机制,有3条基本的准则,通过这些准则可判断变量的大小。 typedef和#define语句都可用于给已存在的类型取个别名,但两者有细微差别,#define是编译预处理指令,在编译之前进行字面替换,而typedef是编译阶段的替换,typedef另一个重要的应用方面是函数指针,在指针进阶一章中会讲到。,

    注意事项

    本文(第14章结构体、共用体、枚举和typedef.ppt)为本站会员(本田雅阁)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开