已阅读5页,还剩43页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第11章复杂数据类型 本章要点理解结构体的含义 定义与使用方法理解共用体的含义 定义与使用方法理解枚举类型的含义 定义与使用方法理解typedef的作用与使用方法掌握链表操作的基本方法本章难点有关链表的操作用结构体变量和指向结构体的指针作函数参数 概述 有时 需将不同类型的数据组合成一个有机的整体 以便于引用 这些数据是相互联系的 如一个学生的有关信息 可采用结构体数据结构描述上述信息 11 1结构体 例如 structstudent intnum charname 20 charsex intage charaddr 30 定义一个结构体类型的一般形式为 struct结构体名 成员表列 对各成员都要进行类型说明 成员名定名规则与变量名同 是类型 不是变量名 11 1 1结构体类型的声明 声明的一般形式为 struct结构名 成员1的说明 成员2的说明 成员n的说明 structmedicine charcode 药品代号 charname 药品名称 floatprice 单价 charplace 产地 stuctgoodscaption 来源地 用宏定义的模式 definestustructstudentstu 成员1的说明 成员2的说明 成员n的说明 11 1 2结构体变量 方法一 先定义结构体类型再定义变量名structstudent intnum charname 20 charsex intage charaddr 30 structstudentstudent1 student2 定义studet1和sudent2为structstudent类型变量 不能只指定一个变量为 struct型 而不指定结构体名 有时 可用符号常量代表一个结构体类型 如 defineSTUDENTstructstudentSTUDENT intnum charname 20 charsex intage charaddr 30 这样 可直接用STUDENT定义变量 如 STUDENTstudent1 student2 此时 不必再写关键字struct 方法二 在定义类型的同时定义变量 如 structstudent intnum charname 20 charsex intage charaddr 30 student1 student2 一般形式是 struct结构体名 成员表列 变量名表列 方法三 直接定义结构类型变量 其一般形式是 struct 成员表列 变量名表列 此时 不出现结构体名 结构体变量的存储 structtest intm1 10 charm2 floatm3 doublem4 aa sizeof structtest 的值为2 10 1 4 8 33 一个结构体变量所占用内存空间的字节数可以用sizeof运算符求出 它的一般形式为 sizeof 变量名或类型标识符 几点说明 1 类型与变量是不同概念 不要混淆 2 结构体中的成员 可以单独使用 其作用与地位相当于普通变量 3 成员也可以是一个结构体变量 例如 structdate intmonth intday intyear Structstudent intnum charname 20 intage structdatebirthday student1 student2 4 成员名可以与程序中的变量名相同 二者不代表同一对象 11 1 3结构体变量的引用与初始化 规则 1 不能将一个结构体变量作为一个整体进行赋值和输出 只能对其各个成员分别输出 引用形式为 结构体变量名 成员名 printf student1 printf d student1 num 输出10010 错 正确 2 若成员本身又属一个结构体类型 只能对最低级的成员进行赋值或存取以及运算 如 student1 birthday year 下页续 接上片 3 对成员变量可以象普通变量一样进行各种运算 如 sumage student1 age student2 age 4 可以引用成员的地址 也可以引用结构体变量的地址 如scanf d 错 输入student1 num的值 输出student1的首地址 结构体变量的初始化 一 对外部存储类型的结构体变量初始化 structstudent longintnum charname 20 charsex charaddr 20 a 9801 Wanghong W 2LinggongRoad main printf No ld nname s nsex c naddress s n a num a name a sex a addr 运行结果为 No 9801name Wanghongsex Waddress 2LinggongRoad 二 对静态存储类型的结构体变量初始化 如 main staticstructstudent longintnum charname 20 charsex charaddr 20 a 9801 Wanghong W 2LinggongRoad printf No ld nname s nsex c naddress s n a num a name a sex a addr 11 1 4结构体数组 每个数组元素都是一个结构体类型的数据 一 结构体数组的定义 如structstudent intnum charname 20 charsex intage charaddr 30 structstudntstu 3 也可直接定义 如structstudent intnum stu 3 或struct intnum stu 3 二 结构体数组的初始化 只能对全局的或静态存储类别的数组初始化 structstudent intnum charname 20 charsex intage charaddr 30 stu 3 111 Li M 18 Dalian 也可采用 structstudent intnum structstudentstu 结构体数组的初始化的一般形式是在定义数组后面加上 初值表列 例题 设有三个候选人 每次输入一个得票的候选人的名字 要求最后输出各人得票结果 structperson charname 20 intcount leader 3 Li 0 zhang 0 Liu 0 main inti j charleader name 20 for i 1 i 10 i scanf s leader name for j 0 j 3 j if strcmp leader name leader j name 0 leader j count for i 0 i 3 i printf 5s d n leader i name leader i count 11 1 5结构体指针 定义格式为 struct结构名 结构体 struct结构名变量名1 变量名2 变量名n 指针变量名1 指针变量名2 指针变量名n 指针变量名1 1 指向结构变量的指针变量 结构体变量的指针 是该结构体变量所占居的内存段的起始地址 例如 main structstudent longintnum charname 20 charsex structstudentstu 1 structstudent p p stu 1 stu num 9901 strcpy stu 1 name LiMin stu 1 sex W printf No ld nname s nsex c n stu 1 num stu 1 name stu 1 sex printf nNo ld nname s nsex c n p num p name p sex 引用结构体成员的三种形式 结构体变量名 成员名 p 成员名p 成员名 指向运算符 其优先级高于自增 自减运算符 试分析以下运算 p n得到p指向的结构体变量中的成员n的值p n 得到p指向的结构体变量中的成员n的值 用完后使它加1 p n得到p指向的结构体变量中的成员n的值使其先加1 2 指针变量的引用 指向结构数组的指针变量 我们知道 数组和指针有密切的关系 同样 结构数组和结构数组指针也紧密相关 当定义一个结构数组后 我们还可以定义一个结构指针变量 使该指针变量指向这个数组 那么 程序中既可以利用数组下标访问一个数组元素 也可以通过指针变量的操作来存取结构数组元素 例如 定义一个结构类型worker和结构数组class structworker charname 20 floatsalary intage intnum 12 structworkerclass 10 structworker pa pa 指针变量pa指向结构体数组的首地址 定义stu1是类型为structstudent的结构体变量 pa是可以指向该类型对象的指针变量 但应该注意的是 经过上面的定义 此时pa尚未指向任何具体的对象 为使pa指向stu1 必须把stu1的地址赋给pa pa 注意 在定义了 pa之后 应该知道 1 pa不是结构变量 因此不能写成pa ave 必须加上圆括号 ps ave 为此 C语言引入一个指向运算符 连接指针变量与其指向的结构体变量的成员 为间接成员运算符 其一般引用的格式为 指针变量名 结构成员名说明 运算符 是由连字符和大于号组成的字符序列 它们要连在一起使用 C语言把它们作为单个运算符使用 所以我们可以将 ps ave改写为ps ave 2 pa只能指向一个结构体变量 而不能指向结构体变量中的一个成员 3 指向运算符 的优先级别最高 11 1 6结构体与函数 1 结构体作为函数参数结构体变量做函数参数有三种方法 一是 C语言允许用结构变量的成员做函数参数例如 structstu floatscore stu1 voidshow stu1 score voidshow floatx 语句序列 二是 C语言允许用结构变量做函数的参数例如 show stu1 三是 结构指针做函数参数 和普通变量一样 结构体变量作为函数参数 用于在函数之间传递数据 同时 函数的返回值也可以是结构变量 结构变量作函数参数的传递方式与简单变量作函数参数的处理方式完全相同 即采用值传递的方式 形参结构变量中各成员值的改变 对相应实参结构变量不产生任何影响 但在函数定义时需要对其类型进行相应的说明 如 intget month x structmonthx x day 25 它说明了形参x是structmonth型结构变量 在定义结构体类型的函数时 需要说明返回值的类型为相应的结构类型 例如 structdatafunc n floatm structdataf return f 其中 函数名func前面的类型说明符就是用于对函数返回值f的类型进行说明 2 结构体类型的函数 结构体函数的一般定义形式为 struct结构类型名函数名 形式参数列表 函数体 11 1 7结构体嵌套 例如 structdate intyear intmouth intday structhome charpost 6 charadd 80 chartele 40 structstu charname charsex structdatebirthday structhomeh floatscore s1 10 如果一个结构成员是另一个结构体的成员变量 这种数据组织叫着结构嵌套 11 2用结构体指针操作链表 11 2 1链表概述链表是将若干数据项按一定规则连接起来的表 链表中的每个数据称为一个结点 即链表是由称为结点的元素组成的 结点的多少根据需要确定 链表连接的规则是 前一个结点指向下一个结点 只有通过前一结点才能找到下一个结点 因此 每个结点都应包括两方面的内容 1 数据部分 该部分可以根据需要由多少个成员组成 它存放的是需要处理的数据 2 指针部分 该部分存放的是一个结点的地址 链表中的每个结点通过指针连接在一起 我们可以对链表进行归类 当然一个链表必须要知道其表头的头指针 如果一个链表中的结点只有一个指向其他结点的指针 则称为单链表 若结点有两个指向其他结点的指针 则称为双链表 单链表结点的类型定义 struct结构名 数据成员列表 struct结构名 指针名 结构体中struct结构名 指针名 表示成员指针所指对象的类型就是自身结点类型 例如 structsture intnum charname 10 charsex structstu node structstures1 定义结点数据域 structstu node next 定义结点指针域 structstu node head 定义可指向结点的指针变量head 11 2 2动态内存管理函数 1 malloc size 函数函数原型 void malloc unsignedsize 功能 在内存的动态存储区的自由内存部分中分配一个长度为size字节的连续内存区域 返回值 如果执行成功 它的返回值是该内存区域首字节的指针 如果执行不成功 它的返回值是0 即NULL 2 calloc n size 函数函数的原型 void calloc unsignedn unsignedsize 功能 在内存的动态存储区的自由存储部分中分配n个长度为size字节的连续内存区域 返回值 如果执行成功 它的返回值为连续内存区域首字节的指针 如果执行不成功 它的返回值是0 即NULL 3 free ptr 函数函数原型为 voidfree void ptr 功能 释放由ptr指向的内存 被释放的内存还回给系统 并成为自由内存 ptr是指针或指针变量 它的值通常是由malloc或calloc函数调用时返回的值 11 2 3链表的基本操作 对链表的基本操作有建立 查找 删除和修改等 1 建立链表是指从无到有建立一个链表 即往空链表中依次插入一个结点 并保持结点之间的前驱和后继的关系 2 查找操作是指在给定的链表中 查找具有检索条件的结点 3 插入操作是指在某两个结点之间插入一个新的结点 4 删除操作是指在给定的链表中 删除某个特定的结点 也就是插入的逆过程 5 修改操作是指在给定的链表中 首先根据某已知的条件 查找到该结点 再修改数据域中的某些数据项 11 2 4结点的插入与删除 1 结点的插入链表的插入是将一个结点插入到已存在的线性链表的指定位置 假设已经存在线性链表的长度为N 将一个给定的结点插入到它的第i个结点之前 其中1 i N 1 插入分三种情况进行讨论 一是 i 1 这时需将一个待插入结点插入在线性链表的第一个结点之前 方法是 将待插入结点的指针域设置为原来的头指针 即将原来的第一个结点作为待插入结点的直接后续 置头指针变量为待插入结点的指针 二是 1 i n 1这时需将一个待插入结点插入在线性链表第i 1与第i个结点之间 方法是 将待插入结点的指针域置为第i 1个结点的指针域 三是 i n 1这时需将一个待插入结点插入在线性链表的尾结点之后 方法是 待插入结点的指针域置空 即尾结点的指针域值 将线性链表的尾结点的指针置为待插入结点的指针 即将线性链表尾接点作为待插入接点的直接前驱 2 结点的删除所谓链表的删除就是删除存在的线性链表的指定的结点 假设已存在的线性链表的长度为n 删除第i个结点 其中1 i n 则删除的问题分三种情况进行讨论 一是 i 1这时需要删除的结点是线性链表的第一个结点 方法是 置头指针变量为第一个结点的指针域 即将原来的第二个结点的指针作为新链表的头指针 二是 1 i n这时需要将第i 1个结点作为第i 1个结点的直接后续 方法是 将第i 1个结点指针域置为第i个结点指针域三是 i n这时需要删除的结点是线性链表的尾结点 方法是 将第i 1个结点指针域置为空 即尾结点的指针域值 例题 假设学生链表的接点类型为structst 请编写函数structst structst head longkey 功能是从头指针为head的学生链表中删除学号为key的那个结点structst longnum charname 12 intscorestructst next structst del structst head longkey structst p pre p head while p num key 返回结点删除以后链表的头指针 11 2共用体 11 2 1共用体变量的定义共用体 使几个不同的变量共占同一段内存的结构 称为 共用体 类型的结构 共用体 类型变量的定义形式为 union共用体名 成员表列 变量表列 例如 uniondata inti charch floatf a b c 或uniondata inti charch floatf uniondataa b c 或union inti charch floatf a b c 直接定义 先定义类型 11 2 2共用体变量的引用 注意 只能引用共用体变量中的成员 不能引用共用体变量本身 如 可以引用a i 引用共用体变量中的整型变量i a ch 引用共用体变量中的字符变量ch a f 引用共用体变量中的实型变量f 不能只引用共用体变量 如 printf d a 错误 总结 共用体类型数据的特点 1 每一瞬时只有一个成员起作用 2 共用体变量中起作用的成员是最后一次存放的成员 3 共用体变量的地址和它的各成员的地址都是同一地址 4 不能对共用体变量名赋值 也不能企图引用变量名来得到成员的值 又不能在定义共用体变量时对它初始化 5 不能把共用体变量作为函数参数 也不能使函数带回共用体变量 但可使用指向共用体变量的指针 6 共用体类型可以出现在结构体类型定义中 也可以定义共用体数组 而结构体也可以出现在共用体类型定义中 数组也可以作为共用体的成员 注意共用体类型变量与结构体类型变量的区别 结构体类型变量所占内存长度是各成员占的内存长度之和 共用体类型变量所占内存长度等于最长的成员的长度 共用体与结构体的嵌套 例设有一个教师与学生通用的表格 教师数据有姓名 年龄 职业 教研室4项 学生有 姓名 年龄 职业 班级4项 编程输入人员数据 再以表格输出 main struct charname 10 intage charjob union intclass charoffice 10 depa boby 2 intn i for i 0 i 2 i printf inputname age jibanddepartment n scanf s d c boby i name for i 0 i 2 i if boby i job s printf s t 3d 3c d n boby i name boby i age boby i job boby i depa class elseprintf s tt 3d 3c s n boby i name boby i age boby i job boby i depa office 11 3枚举类型 若一个变量只有几种可能的值 可以定义为枚举类型 所谓 枚举 是指将变量的值一一列举出来 变量的值只限于列举出来的值的范围内 定义方法 先定义枚举类型enumweekday sun mon tue wed thu fri sat 再用此类型定义变量 如 enumweekdayworkday week end 或直接定义枚举变量 如 enumweekday sun mon tue wed thu fri sat workday week end 说明 枚举元素为常量 不是变量 故不能对它们赋值枚举常量有值 如上面定义中 sun mon tue sat的值依次为0 1 2 7也可改变枚举元素的值 在定义时指出 如 enumweekday sun 7 mon 1 tue wed thu fri sat 枚举值可用来作判断比较 如 if workday mon if workday sun 一个整数不能直接赋值给一个枚举变量 应先进行强制类型转换才能赋值 如 workday enumweekday 2 相当于将序号为2的枚举元素值赋给workday 即 workday tue 例枚举类型运用 main enumworkday sun 7 mon 1 tue wed fri thu sat today tomorrow today sat tomorrow today 7 1 printf today d n today if tomorrow 7 printf tomorrowisSunday n today 6tomorrowisSunday scanf s 11 4typedef类型声明 C语言允许用typedef说明一种新的数据类型名 其一般形式为 typedef类型名1类型名2 其中 关键字typedef用于给已有类型重新定义新类型名 类型名1为系统提供的标准类型名或是已定义过的其他类型名 类型名2为用户自定义的新类型名 它往往可以简化程序中变量的类型定义 例如 typedefintWORD 定义WORD等价于数据类型int 此后 就可用WORD对变量进行类型说明 如 WORDa b c pa 实际上 C编译程序把上述变量作为一般的整型变量处理 在这种情况下 变量所表示的含义较为清楚 从而增加了程序的可读性 对typedef的几点使用说明如下 1 typedef不能用于变量的定义 只能对已存在的类型增加新的类型名 而不能定义新的类型 2 从表面上看 typedef与 define的使用方式十分相似 但两者本质上是不同 例如 typedefintCOUNT defineCOUNTinttypedef定义的是一种新的数据类型 类型名为COUNT 它是系统标准类型 int 的别名 在预编译时 编译器会将COUNT与int作为同一个类型来处理 define定义的是一个宏 宏名为COUNT 在预编译时 编译器
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 初中数学课三公开课获奖教案设计设计
- 脑疝病人的护理培训
- 初中数学说课稿(集合15篇)
- 博山区城市绿地养护管理项目监理招标文件
- 全国爱牙日教育活动课件模板
- 初高中基础词汇测试
- 主动脉弓部病变烟囱技术模拟操作技巧
- 以北京卫视为例,分析其优劣势,市场机会和威胁
- 毕业论文工作总结
- 中英文论文对照格式
- 财税201758号文深度解析:工程项目预收账款财税处理大调整
- 静配中心PDCA成果汇报品管圈课件-提高静配中心废弃物分类合格率
- 中国农业文化遗产与生态智慧智慧树知到期末考试答案章节答案2024年浙江农林大学
- ZJ70DB钻机系统设计与研究
- GB/T 43803-2024科研机构评估指南
- 中国当前周边安全形势
- 中药代茶饮行业市场分析
- 2024年北京市公务员录用考试申论真题及解析
- DB21-T 2986.6-2018公共场所风险等级与安全防护 第6部分:图书场馆
- 集团关键岗位员工定期轮岗制度
- 脑栓塞取栓护理查房
评论
0/150
提交评论