




已阅读5页,还剩47页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
全国计算机等级考试2C课程 第十一讲结构体 共用体和用户定义类型 1 结构体的概念 在实际问题中 一组数据往往具有不同的数据类型例如 学生表中 姓名 性别为字符型 学号 年龄为整型 成绩为实型 家庭地址为字符数组等等 显然 用数组来存放这组数据是不可行的 为了解决这类问题 语言中给出了另一种构造数据类型 结构 structure 或叫 结构体 与数组相比 结构体是一种功能更为强大的构造类型的数据 它可以把一组不同类型的数据组合成一个整体 2 结构体类型的定义 定义结构体类型的一般形式 struct 结构体名 数据类型1成员名1 数据类型2成员名2 数据类型n成员名n 3 结构体类型的定义 说明 struct是定义结构体类型所用的关键字 结构体名 成员名都是用户标识符 其中结构体名也可以省略 无名结构体 成员名1 n也是用户标识符 既可以是基本类型 也可以是其他构造类型 同一结构体中的成员名不可同名 定义结构题语句最后的分号不可省略 结构体类型定义只是规定了该结构体类型的组成形式 编译程序并不会给结构体类型分配存储空间 4 结构体变量的定义 定义了结构体类型后 就可以利用它来定义相应的结构体变量了 其方法如下所示 structstudent intnum charname 20 charsex intage floatscore charaddr 30 structstudentstu1 stu2 5 结构体变量的定义 也可以在定义结构体类型的同时直接定义变量 如 struct intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 说明 本例中 结构体类型没有被命名 这称为无名结构体 无名结构体可以直接定义变量 但本类型只能使用一次 后面无法再用 6 结构体变量的定义 说明结构体成员名可以与程序中的变量名相同 二者不代表同一对象 结构体类型与结构体变量是完全不同的概念结构体类型是用户自定义的一种结构型的数据类型 定义它的过程并不占用系统内存 你不能给一种结构体类型赋值 当然也不能对它进行运算 结构体变量就是具有特定结构体类型的变量 编译时系统将为其分配相应的存储空间 我们可以对其进行赋值 存取以及运算 7 结构体变量的定义 structstudent intnum charname 20 charsex intage floatscore charaddr 30 这是结构体定义 它只描述结构的组织形式 student是结构体类型名 编译时并不为它分配内存 这是结构体变量的定义 编译时 系统将为stu1的每个成员分配如下内存 例如 structstudentstu1 8 结构体变量的定义 结构体成员可以是普通变量 也可以是另一个结构体变量 也就是说结构体可以嵌套使用 如 structdate intmonth intday intyear structstudent intnum charname 20 structdatebirthday stu 又如 structstudent intnum charname 20 structdate intmonth intday intyear birthday stu 例中 结构体变量stu占用内存的情况如下所示 9 小练习 1 下面结构体的定义语句中 错误的是 2009年9月 A structord intx inty intz structorda B structord intx inty intz structorda C structord intx inty intz a D struct intx inty intz a 10 结构体变量的引用 在定义了结构体变量以后 当然可以引用这个变量 引用规则 结构体中的成员只能单独使用 它的作用与地位相当于普通变量 引用方式有三 结构体变量名 成员指针变量名 成员 指针变量名 成员 是成员 分量 运算符 是结构指向运算符 它们与前面所讲的下标运算符 圆括号运算符 的优先级均为1 结合性从左向右 11 结构体变量的引用 使用成员 分量 运算符 引用结构体成员一般形式 结构体变量名 成员 如 structstudent intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 stu1 score 85 5 stu1 num 10 stu1 score stu2 score stu1 age 12 结构体变量的引用 使用结构指针变量 往往能更方便地访问结构变量的各个成员 一般形式 结构指针变量 成员名或 结构指针变量 成员名例如 pstu num或者 pstu num 其中 pstu 两侧的括号不可少 因为成员符 的优先级高于 如写作 pstu num则等效于 pstu num 意义就完全不对了 13 结构体变量的引用 例如 structstu intnum char name charsex floatscore boy1 102 Zhangping M 78 5 pstu main pstu 14 结构体变量的引用 例中 printf语句试图整体引用结构体变量stu1的用法是不可行的 例如 structstudent intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 printf d s c d f s n stu1 引用结构体变量注意事项 1 不能将一个结构体变量作为一个整体进行输入和输出 15 结构体变量的引用 引用结构体变量注意事项 2 但是 将一个结构体变量赋值给另一个结构体变量是允许的 例如 structstudent intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 stu1 stu2 16 结构体变量的引用 引用结构体变量注意事项 3 对于嵌套的结构体 内部成员可以逐级引用 例如 structstudent intnum charname 20 structdate intmonth intday intyear birthday stu1 stu2 stu1 birthday month 12 17 结构体变量的引用 引用结构体变量注意事项 4 不能对结构体变量做关系运算 例如 structstudent intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 if stu1 stu2 例中 语句if stu1 stu2 是错误的 18 小练习 2 有以下程序 2009年3月 includestructord intx y dt 2 1 2 3 4 main structord p dt printf d p x printf d n p y 程序的运行结果是A 1 2B 2 3C 3 4D 4 1 19 结构体变量的赋值 在定义同时初始化 如 structstudent intnum charname 20 charsex intage charaddr 30 stu1 112 WangLin M 19 200BeijingRoad 20 结构体变量的赋值 先定义 后赋值 如 structstudent intnum charname 20 charsex intage floatscore charaddr 30 stu1 stu2 stu1 score 85 5 stu1 num 10 stu1 score stu2 score stu1 age 21 小练习 3 设有定义 2010年3月 structcomplex intreal unreal data1 1 8 data2 则以下赋值语句中错误的是A data2 data1 B data2 2 6 C data2 real data1 real D data2 real data1 unreal 22 小练习 4 有以下定义和语句 2010年3月 structworkers intnum charname 20 charc struct intday intmonth intyear s structworkersw pw pw 23 函数之间结构体变量的数据传递 函数之间结构体变量的数据传递分以下几种情况 1 向函数传递结构体变量的成员 按值传递 2 向函数传递结构体变量 按值传递 3 向函数传递结构体的指针 按地址传递 例如 include stdio h structAB chara 10 intb getdata structAB p scanf s d 24 小练习 5 有以下程序 2010年3月 include includestructA inta charb 10 doublec voidf structAt main structAa 1001 ZhangDa 1098 0 f a printf d s 6 1f n a a a b a c voidf structAt t a 1002 strcpy t b ChangRong t c 1202 0 程序运行后的输出结果是A 1001 zhangDa 1098 0B 1002 changRong 1202 0C 1001 ehangRong 1098 0D 1002 ZhangDa 1202 0 25 用typedef定义的类型 typedef的功能用自定义的名字为已有的数据类型重新命名类型定义后 可以与已有的类型一样使用定义形式 typedeftypename 其中 typedef是类型定义语句关键字type为已有数据类型名name是用户自定义的类型名 例 typedefintINTEGER typedeffloatREAL 类型定义后 就可以与已有的类型一样使用 26 用typedef定义的类型 说明 typedef没有并创造新的数据类型typedef只能定义类型 不能定义变量typedef与define不同 27 小练习 6 有以下程序 2009年9月 includetypedefstruct intnum doubles REC voidfun1 RECx x num 23 x s 88 5 main RECa 16 90 5 fun1 a printf d n a num 程序运行后的输出结果 1 28 动态存储分配 动态存储分配的概念变量 数组一旦定义 其存储长度在整个程序中是固定不变的 因此被称为 静态存储分配 然而 实际编程中 有时候所需的内存空间取决于实际输入的数据 无法预先确定 为了解决上述问题 语言提供了一些内存管理函数 可以按需要动态地分配内存空间 也可把不再使用的空间回收 释放 这种机制称为 动态存储分配 常用的动态存储分配函数有以下三个 分配内存空间函数malloc分配内存空间函数calloc释放内存空间函数free使用以上函数必须有文件包含命令 include stdlib h 29 动态存储分配 分配内存空间函数malloc调用形式 类型说明符 malloc size 功能 在内存的动态存储区分配一块长度为 size 字节的连续区域返回值 函数的返回值为该区域的首地址说明 其中 类型说明符 表示把该区域用于何种数据类型 类型说明符 表示把返回值强制转换为该类型的指针 size 是一个无符号整数例如 char pc pc char malloc 100 表示动态分配100个字节的内存空间 并强制转换为字符数组类型 函数的返回值为指向该字符数组的指针 把该指针赋予指针变量pc 30 动态存储分配 分配内存空间函数calloccalloc也是用于动态分配内存空间 调用形式 类型说明符 calloc n size 功能 在内存动态存储区中分配n块长度为 size 字节的连续区域 函数的返回值为该区域的首地址返回值 该内存区域的首地址说明 类型说明符 用于强制类型转换 calloc函数与malloc函数的区别仅在于一次可以分配n块区域 例如 structstu ps struetstu calloc 2 sizeof structstu 其中sizeof structstu 是求stu的结构长度 该语句的意思是 按stu的长度分配2块连续区域 强制转换为stu类型 并把其首地址赋予指针变量ps 31 动态存储分配 释放内存空间函数free调用形式 free void ptr 功能 释放ptr所指向的一块内存空间说明 ptr是一个任意类型的指针变量 它指向被释放区域的首地址 注意 被释放区域应是由malloc或calloc函数所分配的内存区域 例如 free pc free ps 32 动态链表的概念 如果采用动态分配的办法存储学生记录 一次仅为一条记录动态分配一块空间 我们称之为结点 这样就无须预先确定学生的人数 如果某学生退学 也可删去该结点 并释放该结点占用的存储空间 每个结点之间物理上也可以是不连续的 结点之间的联系用指针来实现 即在结点结构中定义一个成员项存放下一结点的首地址 我们把这个成员称为指针域 在第一个结点的指针域内存入第二个结点的首地址 在第二个结点的指针域内又存放第三个结点的首地址 如此串连下去直到最后一个结点 最后一个结点因无后续结点连接 因此可将其指针域置为空 NULL 以上所述的这种存储数据的方式 在数据结构中称为 链表 33 动态链表的概念 链表的组成 链表中的所有结点都是同一种结构类型 链表包括 一个头指针 是一个结构类型的指针变量 专门用来存放链表第一个结点的首地址 若干个结点 用来存放用户需要的实际数据以及后续链接节点的指针 下图为一简单链表的示意图 说明 头结点head没有数据域 只负责存放第一个结点的首地址 除head外 每个结点都分为两个域 其中数据域存放各种实际的数据 如学号 姓名等 指针域存放下一结点的首地址 34 动态链表的概念 链表的结点链表的结点都是结构体类型 如structstudent intnum floatscore structstudent next 其中成员num和score用来存放结点中用户需要用到的数据 next是指针类型的成员 它指向structstudent类型数据 也就是next所在的结构体类型 35 链表操作示例 定义链表的结点结构 代码如下 typedefstructnode charname 20 structnode link stud 以上代码定义了一个单链表的结构 其中charname 20 是一个用来存储姓名的字符数组 指针变量link用来存储其直接后继结点的首地址 定义了链表的结构之后 就可以动态创建链表的结点 并在其数据域中存储必要的数据 如有后继结点 则将链域指向其直接后继结点 若没有 则将链域置为NULL即可 36 链表操作示例 创建链表 代码如右 stud creat intn stud p h s inti if h stud malloc sizeof stud NULL printf 不能分配内存空间 returnNULL h name 0 0 把表头结点的数据域置空 h link NULL 把表头结点的链域置空 p h p指向表头结点 for i 1 ilink s printf 请输入第 d个人的姓名 i gets s name s link NULL p s return h 注意 由于用到malloc函数 所以在程序的开始部分应有如下包含命令 include 37 链表操作示例 遍历链表 代码如下 main stud head head creat 3 list head voidlist stud head stud p q p head while p link NULL q p link printf s n q name p q 调用创建和输出链表子函数的主函数如下 38 链表操作示例 检索链表中的结点思路 对单链表的结点依次扫描 检测其数据域是否是我们所要查找的值 若是 返回该结点的指针 否则返回NULL stud search stud head char x stud p p head link while p NULL if strcmp p name x 0 returnp elsep p link if p NULL printf 没有查找到该数据 returnNULL 39 链表操作示例 测试结点检索函数的主函数如下 main charfullname 20 stud head searchpoint head creat 3 printf 请输入你要查找的人的姓名 scanf s fullname searchpoint search head fullname printf 你要查找的人的姓名 s n searchpoint name 40 链表操作示例 在单向链表中插入新结点在单向链表中插入新结点的方法步骤如下 1 先创建一个新结点p 2 将q结点的指针域赋值给新结点p的指针域 3 将新结点p的首地址赋值给q的指针域 通过以上3步 即可在链表中q结点的后面插入p结点 如下图所示 41 链表操作示例 在单向链表中指定结点后插入新结点的代码如下 voidinsert stud q stud p if p stud malloc sizeof stud NULL printf 不能分配内存空间 exit 0 printf 输入要插入学生的姓名 gets p name p link q link q link p 42 链表操作示例 测试插入结点函数的主函数 main charfullname 20 stud head searchpoint head creat 2 printf 输入要在他之后添加结点的那个人的姓名 gets fullname searchpoint search head fullname insert searchpoint printf 插入新节点后的链表如下 n list head 43 链表操作示例 删除单向链表中的结点分析 在链表内删除节点有三种不同的情形 1 删除第一个节点 只需要将head的链域指向第二个节点2 删除最后一个节点 只需要将指向最后一个节点的链域赋值为NULL3 删除中间节点 将需要删除节点的前一个结点的链域指向需要删除节点的下一个节点 stud del stud head stud x stud p if x head returnhead link else p head while p link x p p link if x link NULL p link NULL elsep link x link returnhead 44 链表操作示例 测试删除结点函数的主函数 main charfullname 20 stud head searchpoint head creat 3 printf 请输入要删除的学生的姓名 scanf s fullname searchpoint search head fullname del head searchpoint printf 删指定结点后的链表如下 n list head 45 链表操作示例 销毁一个链表链表使用完毕后建议销毁它 因为链表本身会占用内存空间 如果一个系统中使用了很多链表 而使用完毕后又不及时销毁它 那么这些垃圾空间积累过多 最终可能导致内存泄漏甚至程序崩溃 voiddestroy stud head stud p q p head while p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025北京市通州区新华街道社区卫生服务中心招聘非在编药学人员模拟试卷及答案详解(历年真题)
- 2025湖北武汉市中南财经政法大学教师招录模拟试卷及答案详解(夺冠系列)
- 2025广东阳江市阳春市招聘乡村公益性岗位32人(第三批)考前自测高频考点模拟试题及答案详解(新)
- 2025年安康市市本级就业见习岗位(458人)考前自测高频考点模拟试题有答案详解
- 2025贵州省第二人民医院第十三届贵州人才博览会引才招聘13人模拟试卷及参考答案详解1套
- 2025广西贺州市富川瑶族自治县公安局第一次公开招聘警务辅助人员8人模拟试卷及完整答案详解一套
- 2025湖北恩施州巴东水之星体育文化发展有限公司招聘模拟试卷及一套完整答案详解
- 2025江西吉安市永新县面向社会招聘城市社区专职网格员37人考前自测高频考点模拟试题及完整答案详解1套
- 2025河北沧州孟村饶安高级中学招聘1人模拟试卷附答案详解(典型题)
- 2025黑龙江青冈县中小微企业服务中心招聘公益性岗位2人模拟试卷及参考答案详解
- 临时展览搭建与施工方案
- 从国内外角度对人工智能未来发展探索及影响的研究报告
- 成人反流误吸高危人群全身麻醉管理专家共识(2025版)解读 3
- 淀粉加工工培训考核试卷及答案
- 网站推广代理服务合同5篇
- 2025年燃气职业技能鉴定全真模拟模拟题【各地真题】附答案详解
- 2025-2026学年辽海版(2024)小学美术二年级上册《巧用材料》教学设计
- 2025中数联物流科技(上海)有限公司招聘考试参考试题及答案解析
- 具身智能+农业种植智能农业机器人应用研究报告
- 量子计算在人工智能领域的发展趋势与2025年应用案例分析报告
- 医疗风险与安全培训课件
评论
0/150
提交评论