




已阅读5页,还剩60页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章结构体 结构体 共用体 1 思考一个问题 在程序里表示一个人的信息 姓名 年龄 性别 怎么表示 表示多个人呢 如何用计算机程序实现下述表格的管理 表8 1某学校学生成绩管理表 数组的解决方法 intstudentId 30 最多可以管理30个学生 每个学生的学号用数组的下标表示 charstudentName 30 10 charstudentSex 30 2 inttimeOfEnter 30 入学时间用int表示 intscoreComputer 30 计算机原理课的成绩 intscoreEnglish 30 英语课的成绩 intscoreMath 30 数学课的成绩 intscoreMusic 30 音乐课的成绩 数组的解决方法 intstudentId 30 1 2 3 4 5 6 charstudentName 30 10 令狐冲 林平之 岳灵珊 任莹莹 charstudentSex 30 2 男 男 女 女 inttimeOfEnter 30 1999 1999 1999 1999 intscoreComputer 30 90 78 89 78 intscoreEnglish 30 83 92 72 95 intscoreMath 30 72 88 98 87 intscoreMusic 30 82 78 66 90 数组的解决方法 数据的内存管理方式 数组的解决方法 分配内存不集中 寻址效率不高对数组进行赋初值时 容易发生错位结构显得比较零散 不容易管理 希望的内存分配图 结构体的解决方法 structSTUDENT intstudentID 每个学生的序号 charstudentName 10 每个学生的姓名 charstudentSex 4 每个学生的性别 inttimeOfEnter 每个学生的入学时间 intscoreComputer 每个学生的计算机原理成绩 intscoreEnglish 每个学生的英语成绩 intscoreMath 每个学生的数学成绩 intscoreMusic 每个学生的音乐成绩 structSTUDENT是一个类型structSTUDENTstudents 4 students 0 studentNamestudents 0 Sex它们都是变量 一般称为结构的成员变量 8 1结构体的定义 结构体类型的定义结构体类型变量的引用结构体变量的初始化 structstudent intnum charname 20 charsex intage charaddr 30 是数据类型 不是变量名 对各成员都要进行类型说明 成员名定名规则与变量名同 一 结构体类型的定义 一般形式为 struct结构体名 成员表列 方法一 先定义结构体类型再定义变量名structstudent intnum charname 20 charsex intage charaddr 30 structstudentstudent1 student2 定义studet1和sudent2为structstudent类型变量 结构体类型变量的定义 有时 可用符号常量代表一个结构体类型 如 defineSTUDENTstructstudentSTUDENT intnum charname 20 charsex intage charaddr 30 这样 可直接用STUDENT定义变量 如 STUDENTstudent1 student2 此时 不必再写关键字struct 方法二 在定义类型的同时定义变量 structstudent intnum charname 20 charsex intage charaddr 30 student1 student2 一般形式是 struct结构体名 成员列表 变量名列表 方法三 直接定义结构类型变量 其一般形式是 struct 成员表列 变量名表列 此时 不出现结构体名 typedef的用法 功能 定义新类型 即为C语言中已有的数据类型名定义一个新名字 定义格式 typedef标识符1标识符2 structstudent intnum charname 20 charsex intage floatscore charaddr 30 typedefstructstudentSTUD STUDstudent1 student2 用typedef为已存在的类型定义新名字 用STUD代替structstudent类型 几点说明 1 类型与变量是不同概念 不要混淆 2 结构体中的成员 可以单独使用 其作用与地位相当于普通变量 3 成员名可以与程序中的变量名相同 二者不代表同一对象 structdate intmonth intday intyear Structstudent intnum charname 20 intage structdatebirthday student1 student2 4 成员也可以是一个结构体变量 例如 规则 1 不能将一个结构体变量作为一个整体进行赋值和输出 只能对其各个成员分别输出printf student1 printf d student1 num 错 正确 引用形式为 结构体变量名 成员名 二 结构体类型变量的引用 3 对成员变量可以象普通变量一样进行各种运算 如 sumage student1 age student2 age 4 可以引用成员的地址 也可以引用结构体变量的地址 如scanf d 错 输入student1 num的值 输出student1的首地址 2 若成员本身又属一个结构体类型 只能对最低级的成员进行赋值或存取以及运算 如 student1 birthday year 一 对外部存储类型的结构体变量初始化 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 二 对静态存储类型的结构体变量初始化 一 结构体数组的定义structstudent intnum charname 20 charsex intage charaddr 30 structstudntstu 3 也可直接定义 如structstudent intnum stu 3 或struct intnum stu 3 8 2结构体数组 每个数组元素都是一个结构体类型的数据 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 例题 设有三个候选人 每次输入一个得票的候选人的名字 要求最后输出各人得票结果 例如 main structstudent longintnum charname 20 charsex structstudentstu 1 structstudent p p stu 1 Stu 1 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 结构体变量的指针 是该结构体变量所占居的内存段的起始地址 8 3指向结构体类型数据的指针 引用结构体成员的三种形式 结构体变量名 成员名 p 成员名p 成员名 指向运算符 其优先级高于自增 自减运算符 试分析以下运算 成员运算符 得到p指向的结构体变量中的成员n的值使其先加1 p n 得到p指向的结构体变量中的成员n的值 用完后使它加1 p n 得到p指向的结构体变量中的成员n的值 p n for pt stu ptscoreComputer sum 1 sum 1 pt scoreEnglish sum 2 sum 2 pt scoreMath sum 3 sum 3 pt scoreMusic for i 0 i 4 i average i sum i 4 printf 20s 4 2f n name i average i 例8 2 利用指向结构体数组的指针计算学生各科的平均成绩 教材310页 例8 2 main structSTUDENT pt floatsum 4 0 0 average 4 0 0 inti char name scoreofComputer scoreofEnglish scoreofMath scoreofMusic pt stu pt指向结构体数组的第一个元素 for pt stu ptscoreComputer sum 1 sum 1 pt scoreEnglish sum 2 sum 2 pt scoreMath sum 3 sum 3 pt scoreMusic for i 0 i 4 i average i sum i 4 printf 20s 4 2f n name i average i 1 向函数传递结构体的单个成员单向值传递 函数内对结构内容的修改不影响原结构2 用整个结构体变量作实参和形参 向函数传递结构体的完整结构单向值传递 函数内对结构内容的修改不影响原结构 开销大 8 4结构体与函数 结构体参与函数运算的几种形式 3 向函数传递结构体的首地址用结构体数组或者结构体指针做函数参数除提高效率外 还可以修改结构体指针所指向的结构体的内容4 用结构体类型作为函数返回类型 一付扑克有52张牌 分为4种花色 Suit 黑桃 Spades 红桃 Hearts 草花 Clubs 方块 Diamonds 每种花色有13张牌面 Face A 2 3 4 5 6 7 8 9 10 Jack Queen King设计一个结构体表示一张牌 由两个成分组成 花色 牌面 structCARD charsuit 10 charface 10 structCARDcard 52 顺序存放扑克牌 intresult 52 存放洗牌发牌结果 char suit Spades Hearts Clubs Diamonds char face A 2 3 4 5 6 7 8 9 10 jack Queen King 例8 1 洗牌和发牌模拟 发牌过程将52张牌按照随机的顺序存放算法步骤 产生0 51的随机数 将其放于result i 内 i i 1如果i 51 则重复第2步 否则 结束循环输出结果存在一个致命的问题 在重复第2步时 产生的随机数可能与以前产生的随机数相同 相同意味着52张牌中出现2张以上相同的牌 例8 1 洗牌和发牌模拟 解决方法增加一步 判断新产生的随机数以前是否出现过如果出现过 则放弃 如果以前未出现过 则保留算法步骤 产生0 51的随机数m 将其放于result i 内 判断result i 在以前 result 0 result i 1 是否出现过 如果出现过 则回到第2步 如果没出现过 则i i 1如果i 51 则重复第2 3步 否则 结束循环输出结果 例8 1 洗牌和发牌模拟 算法缺陷 随着随机数数量的增加 新的随机数与已经产生的随机数相同的可能性越来越大 有可能出现算法延迟问题高效算法将按照花色与牌面的顺序存放的牌 card i 随机打乱每次循环 程序选择一个0 51的随机数j 然后将数组中当前的CARD结构card i 与随机选出的j所在的数组元素card j 结构进行交换 例8 1 洗牌和发牌模拟 用结构体数组做函数参数voidFillCard structCARDwCard char wFace char wSuit inti for i 0 i 52 i strcpy wCard i suit wSuit i 13 strcpy wCard i face wFace i 13 例8 1 洗牌和发牌模拟 P313 用结构体指针做函数参数voidShuffle structCARD wCard inti j structcardtemp for i 0 i 52 i j rand 52 j random 52 TC的库函数 temp wCard i wCard i wCard j wCard j temp 洗牌过程 例8 1 洗牌和发牌模拟 P313 用结构体指针做函数参数voidDeal structCARD wCard inti for i 0 i 52 i 输出发牌结果 printf 10s 10s n wCard i suit wCard i face 例8 1 洗牌和发牌模拟 P313 思考题 structpoint intx inty structrect structpointpt1 structpointpt2 structrectrt rp 下面表达式哪些合法 rt pt1 x rp pt1 xrp pt1 xrt pt1 x 实验九结构体编程练习在屏幕上模拟显示一个数字式时钟 定义一个时钟结构体类型 structclock inthour intminute intsecond typedefstructclockCLOCK voidupdate CLOCK t t second if t second 60 t second 0 t minute if t minute 60 t minute 0 t hour if t hour 24 t hour 0 voiddisplay CLOCK t printf 2d 2d 2d r t hour t minute t second 实验九结构体编程练习在屏幕上模拟显示一个数字式时钟 内存动态分配函数C语言提供以下几个动态存储分配函数 malloc size calloc n size free ptr 8 5用指针处理链表 1 malloc size 功能 在内存的动态存储区分配一个长度为size的连续空间 此函数的返回值是一个指针 它的值是该分配区域的起始地址 若此函数未能成功地执行 则返回值为0 2 calloc n size 功能 在内存的动态存储区中分配n个长度为size的连续空间 3 free ptr 功能 释放由ptr指向的内存区 ptr是最近一次调用malloc或calloc函数时返回的值 函数返回分配域的起始地址 若分配不成功 返回0 malloc size 与calloc n size 的区别malloc size 不能初始化所分配的内存空间calloc n size 能初始化所分配的内存空间 如果由malloc size 函数分配的内存空间原来没有被使用过 则其中的每一位都可能是0 如果这部分内存空间曾经被分配 释放和重新分配 则其中可能遗留各种各样的数据 calloc n size 函数会将所分配的内存空间的每一位都初始化为0 malloc size 与calloc n size 的返回值处理 malloc size 与calloc n size 的返回值都是void类型的指针 具有一般性 是抽象类型的数据若将函数调用的返回值赋予某指针 则应先根据该指针的基类型 对返回的指针进行强制类型转换 链表的概念链表是一种常见的重要的数据结构 它是动态地进行存储分配的一种结构 链表有一个 头指针 变量 它存放一个地址 该地址指向链表中的第一个元素 如下图所示 链表中每一个元素称为 结点 每个结点都应包括两个部分 数据域 用户需要用的实际数据 指针域 下一个结点的地址 结点1 结点2 结点n 可以看出 头指针head指向第一个元素 第一个元素又指向第二个元素 直到最后一个元素 该元素不再指向其它元素 它称为 链尾 其地址部分存放一个 NULL 表示 空地址 链表到此结束 对于两个相邻的结点p1 p2 p1是p2的直接前驱结点 p2是p1的直接后继结点 由此可以看出 链表中结点必须是结构体类型 其中一个成员是指针类型 这个指针类型指向它所在的结构体类型 其中next是成员名 是指针类型 它指向structlink类型数据 例如 structlink intdata structlink next 前面只是定义了一个structlink类型 并未实际分配存储空间 可用前述方法在需要时动态地开辟和释放存储单元 例如 include stdlib h p structlink malloc sizeof structlink if p NULL p data 10 p next NULL 其中sizeof 的功能是测试某种类型的变量在内存中所占用的字节数 例如 sizeof float 的值是4 它表示float型变量在内存中占4个字节 free p structLink intdata StructLink next 线性表的链式存储结构 可用C语言中的 结构指针 来描述 带头结点的线性链表 不带头结点的线性链表 1 动态链表的建立 新结点链接在链尾 初态 第一次插入 第n次插入 2 在头指针为h的单链表中查找结点x Structlink dlbcz Structlink h intx Structlink p p h while p NULL structLink intdata StructLink next 3 单链表的插入运算 后插 voiddlbhcr structLink p intx structLink s s structLink malloc sizeof structLink if s NULL s data x s next p next p next s elseprintf unsucess Voiddlbsc structLink p structLink q if p next NULL q p next p next q next free q 4 单链表的删除运算 在单链表中删除p结点的直接后继结点q 5 单链表中直接插入或删除某个结点p 插入某个结点p时需考虑 1 插入点p在第一个结点之前 应修改头指针head及其指向即 p next head head p 2 插入点p在链表中间 应修改插入点前pr结点的指向即 p next pr next pr next p 3 插入点p在链尾 应修改原链表最后一个结点pr指针域的指向 并将新插入的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025安徽蚌埠市怀远县教育局所属事业单位紧缺专业人才引进(校园招聘)15人模拟试卷附答案详解(模拟题)
- 2025内蒙古赤峰市红山区崇文实验学校教师招聘14人模拟试卷完整答案详解
- 2025湖南资兴市面向本市农村订单定向医学生、基层医疗卫生机构本土化专科层次人才培养医学生考核招聘15人考前自测高频考点模拟试题及答案详解(考点梳理)
- 广本安全驾驶课程培训课件
- 协议书协议书5篇
- 广播电视基础知识课件
- 2025年三亚市直属学校赴高校面向2025年应届毕业生招聘81人模拟试卷(含答案详解)
- 小学学生安全培训总结课件
- 小学外出培训安全承诺书课件
- Hydroxylamine-生命科学试剂-MCE
- 梅毒艾滋乙肝三病
- 割灌机安全操作规程培训
- 2024年山西省成考(专升本)大学政治考试真题含解析
- 最高法院第一巡回法庭关于行政审判法律适用若干问题的会议纪要
- 《病历书写基本规范》课件
- 足球场的运营可行性方案
- 重庆市面向西南大学定向选调2024届大学毕业生2024年国家公务员考试考试大纲历年真题3453笔试难、易错历年高频考点荟萃附带答案解析(附后)
- GB/T 2881-2023工业硅
- 小学生电力科普小讲座(课件)-小学常识科普主题班会
- 有限合伙份额质押合同完整版(包含质押登记公证手续)
- GB/T 43299-2023机动车玻璃电加热性能试验方法
评论
0/150
提交评论