




已阅读5页,还剩81页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 第十一章结构体与共用体11 1概述11 2定义结构体类型和定义结构体变量11 3结构体变量的引用11 4结构体变量的初始化11 5结构体数组11 6指针与结构体11 7用指针处理链表 11 8共用体 11 9枚举类型11 10用typedef定义类型 2 11 1概述数组 同类型数据的集合 C构造类型结构体 不同类型数据的集合 共用体 不同类型的量共用存储单元 若 表示学生多门课成绩 各门课成绩数据类型一致 适合用数组表示 若 对一系列整数排序 适合用数组表示 3 若 编程处理若干学生的基本情况 其中每个学生的基本情况由若干项组成 而各项的类型可能相同或不同 项目 学号姓名性别出生日期成绩电话号码数据 类型 长整 字串字串字符字串整型字串该例构成每个学生基本情况的数据类型不同 可采用结构体这种数据类型实现 教工基本情况 工号学院姓名性别工作时间基本工资 4 11 2定义结构体类型和定义结构体变量1 定义结构体类型定义一般形式 struct结构体名 类型标识符成员名1 类型标识符成员名2 类型标识符成员名n 其中 1 struct结构体名组成具体的结构体类型标识符 可用这个结构体类型标识符去定义变量等对象 2 结构体名 成员名应符合标识符命名规则 3 类型标识符确定各成员类型 5 例 定义可表示学生基本情况的结构体类型 项目 学号姓名性别出生日期成绩电话号码数据 类型 长整 字串字串字符字串整型字串structstudent 特定结构体类型标识 longnum charname 20 charsex charbirthday 12 floatscore chartel 15 该类型共有6个成员 6 说明 1 结构体不可能有统一的结构 因此一个结构体的成员数目 各成员的类型必须依据具体情况由用户自己定义 2 一个C程序可定义多个结构体类型 定义的位置可在函数之内 也可在函数之外 位置决定其有效范围 如 结构体类型1定义 voidmain 结构体类型2定义 fun1 类型1有效 类型2有效 7 3 成员名可与程序中其它量同名 且互不干扰 4 成员的类型也可是已定义过的结构体类型 如 structdate 该结构体有3个成员 intm 或intm d y intd inyy structstudent 该结构体有6个成员 longnum charname 20 charsex structdatebirthday 成员类型 结构体 floatscore chartel 15 8 5 定义结构体类型仅仅声明了一种数据结构 编译系统是不会为类型分配存储空间的 此时在有效范围内 可用已定义的结构体类型去定义结构体变量或数组 编译系统将为结构体变量或数组分配存储空间 9 2 定义结构体类型的变量三种定义方法 1 先定义结构体类型 再用类型标识去定义变量structstudentstu1 stu2 structstudent是已定义的结构体类型标识符 stu1 stu2是所定义的结构体变量 编译时将为结构体变量分配各自的存储空间 2 定义类型的同时定义变量structstudent 各成员的定义 stu1 stu2 10 3 不使用结构体名 定义类型的同时定义变量struct 无结构体名 stu1 stu2 说明 结构体变量可以是局部的或全局的 结构体变量存储空间大小为各成员长度之和 如变量stu1存储字节数 sizeof stu1 TC下 4 20 1 6 4 15 50VC下 4 20 1 12 4 15 56 11 结构体变量的存储结构 各成员按定义顺序连续存储 如VC下 structdate intm d y structstudent longnum charname 20 charsex structdatebirthday floatscore chartel 15 stu1 stu2 numnamesexbirthdayscoretel 420112415 共56字节 成员成员字节数 stu1 mdy 12 11 3结构体变量的引用数组引用的单位是元素 而不能引用整个数组 结构体变量引用的单位则是具体成员 同样结构体变量不能被整体引用 1 结构体变量各成员的引用引用形式 结构体变量名 成员名其中 成员运算符 一级 自左而右 如 按以上定义stu1 num引用结构体变量stu1的num成员 stu1 name引用stu1的name成员 字符指针 stu1 name i 引用name成员的第i个元素 stu1 birthday y只能对最低级成员进行引用 13 2 结构体变量各成员的输入 输出应按成员类型选择输入 输出的格式符 例 按以上定义输入scanf ld 成员tel的指针 LiFeng 021 8482500 14 例 按以上定义输出printf nunber 06ld n stu1 num 前导0 printf d d d stu1 birthday y stu1 birthday m stu1 birthday d printf name s n stu1 name 或 for i 0 stu1 name i 0 i 数组成员输出 printf c stu1 name i 说明 与 运算符同为一级 自左而右运算 15 3 成员的赋值1 数值型成员赋值如 stu1 num 60234 不加前导0 stu1 birthday y 1988 stu1 birthday m 5 2 字符数组成员赋值如 strcpy stu1 name LiFeng 错误 stu1 name LiFeng 3 结构体变量间的赋值如 stu2 stu1 注 同类型结构体变量间可直接赋值 其结果是按成员一一对应赋值 16 4 对成员运算如 aver stu1 score stu2 score 2 0 如 stu1 num 1级 2级 先访问成员num 而后num自加1 如 if stu1 score 60 c 17 420112415 5 结构体变量的指针 结构体成员的指针注 优先级为2级 低于 和 图示 numnamesexbirthdayscoretel mdy 变量stu1的指针 stu1num成员指针 stu1 numname成员指针 stu1 namename第i个元素指针 stu1 name i 最低级成员y的指针 stu1 birthday y成员tel的指针 stu1 tel stu1 18 11 4结构体变量的初始化定义结构体变量的同时用初值表给出初值 例 定义结构体变量存放两位学生的基本情况 计算平均成绩 并以大写形式输出name成员 include stdio h structstudent 定义全局结构体类型 longnum charname 20 floatscore voidmain 按成员顺序给出初值 structstudentstu1 109031 LiFeng 89 0 stu2 109032 WangLi 71 0 floataver inti 19 aver stu1 score stu2 score 2 0 printf n taverage 7 2f n aver for i 0 stu1 name i 0 i 处理stu1 if stu1 name i a main 20 11 5结构体数组数组是同类型元素的集合 结构体数组也是同类型元素的集合 只不过每个元素的类型均为相同的结构体类型 前面介绍的结构体变量可用来表示一位学生的基本情况 要表示多个学生的基本情况时 采用结构体数组比较方便 21 1 结构体数组的定义和初始化例 structstudent longnum charname 20 floatscore stu 3 99001 LiFeng 89 5 99002 WangYi 70 5 99003 ZhaoHui 92 说明 1 数组stu各元素类型相同 都为structstudent型 2 结构体数组stu的存储字节数为 元素类型长 元素个数 4 20 4 3 84字节 22 3 结构体数组stu的存储结构 stu 0 stu 1 stu 2 99001LiFeng 089 599002WangYi 070 599003ZhaoHui 092 0 420284 84byte stu 1 scorestu 2 num 23 2 结构体数组的引用结构体数组在引用时 不仅要确定引用哪一个元素 还要确定引用该元素的哪一个成员 引用形式 数组名 下标 成员名其中 运算符 与 同为一级 自左而右结合 过程 依据数组名及下标先定位到元素 然后再定位到成员 如 stu 0 num访问stu数组首元素的成员num stu 0 score访问stu数组首元素的score成员 stu 1 score访问以1为下标那个元素的score成员 24 例 编程求三位学生的平均成绩 并输出成绩最高者的学号 姓名 成绩 voidmain struct 定义局部结构体类型及数组 longnum charname 20 floatscore stu 3 99031 LiLin 89 0 99032 WangFang 71 0 99033 ZhaoPing 92 0 floatmaxs sum 0 inti p 25 voidmain 结构体类型 结构体数组stu的定义及赋初值 floatmaxs sum 0 inti p maxs 0 for i 0 imaxs maxs stu i score p i printf n taverage f n sum 3 0 printf tnum ld name s score 7 2f n stu p num stu p name stu p score 26 例 30张选票 对三名侯选人之一投票选举 输入得票人名字 按名字计数 输出最后选举结果 include stdio h defineN30structperson charname 20 intcount voidmain structpersonled 3 Li 0 Zhang 0 Wang 0 led 0 led 1 led 2 led 0 name led 0 count 27 voidmain structpersonled 3 Li 0 Zhang 0 Wang 0 charlname 20 inti j for i 1 i N i i控制选票张数 printf Input dNO name i gets lname for j 0 j 3 j j控制数组下标 if strcmp led j name lname 0 串比较 led j count 1 break 计票 for i 0 i 3 i printf n 10s d led i name led i count 28 11 6指针与结构体1 指向结构体变量的指针一个结构体变量的指针是该变量存储区域的起始地址 它指向结构体这个整体 在程序中可定义一个指向同类型结构体的指针变量 并将该指针变量指向某结构体变量 之后便可利用指针变量访问各成员 29 例 利用结构体指针 对某学生基本情况赋值并输出 voidmain structstudent longnum charname 20 floatscore stu1 p stu1 num 99001 strcpy stu1 name LiFeng stu1 score 89 5 p p name 0 name 1 name 19 468472473 491492 stu1 30 说明 1 当p p name i 访问p指向变量的name成员第i个元素 31 2 用结构体指针变量访问结构体数组元素 例 输入 输出三位学生基本情况 计算平均成绩 include includestructstudent longnum charname 20 floatscore voidmain structstudent p stu 3 inti floatsum 0 p stu stu 0 stu 1 stu 2 99001LiFeng89 599002WangYi70 599003ZhaoHui92 0 p 32 sqrt 25 TC下激活浮点运算 for i 0 inum p name p score for p stu i 0 iscore 累加成绩 printf taverage 7 2f n sum 3 0 33 说明 1 若p stu p 的增量为元素类型长28 从而使p指向下一个元素 2 当p stu 且保持不变时 p i的值 stu i 元素类型长 stu i 28p i含义 数组元素str i 的地址 即 p i stu i 34 3 结构体指针作为函数参数此时实参与形参对应关系为 实参形参结构体变量 成员成员结构体变量的指针结构体指针变量结构体变量名同类型结构体变量 基本类型变量数组名 成员的值数组成员的指针 与成员同类型变量同类型形参数组 结构体变量的指针 各成员值对应传递 35 例 一结构体类型 可表示学号 姓名 三门课成绩及平均成绩 编程对两位学生的成绩求个人平均分 输出所有数据项 要求 1 分别用结构体变量stu1 stu2存储数据 2 由函数aver实现个人平均分计算 3 由函数pfun实现输出 函数间信息传递 主函数 aver pfun 结构体变量的指针 结构体变量各成员值 无返回值 无返回值 36 源程序 structstudent longnum charname 20 floatscore 3 floataver voidmain structstudentstu1 stu2 定义变量并赋初值 numnamescore 0 score 1 score 2 aver 99001LiHong89 076 090 00 12byte 37 voidmain structstudent 定义结构体变量并赋初值 stu1 99001 LiHong 89 76 90 0 stu2 99002 WangLi 70 5 85 5 76 0 voidaver structstudent p voidpfun structstudents aver 38 voidaver structstudent p inti floatsum 0 for i 0 iscore i p aver sum 3 0 return voidpfun structstudents 实形参对应成员值传递 inti printf t ld t s t s num s name for i 0 i 3 i 输出成绩成员的各元素 printf t 7 2f s score i printf t 7 2f n s aver return 39 例 设计一软件计时器 用字符显示时 分 秒structtime stru 该类型全局有效 inth m s 三个成员用一个标识符 voidmain voidupdata structtime stru t voiddisplay structtime stru t structtime strutime 定义结构体变量 time h time m time s 0 clrscr while kbhit 击键测试 updata 40 voidupdata structtime stru t longi t s 秒成员自加1 if t s 60 t m t s 0 if t m 60 t h t m 0 if t h 24 t h 0 for i 1 ih t m t s return 41 例 TC中调用标准函数 显示系统日期和时间 系统日期函数原形 voidgetdate structdate datep 系统时间函数原形 voidgettime structtime timep dos h头文件中结构体类型的定义 structtime unsignedcharti min unsignedcharti hour unsignedcharti hunt 百分之一秒 unsignedcharti sec structdate intda year charda day charda mon 42 include includevoidmain structdatesysd 定义结构体变量 structtimesyst getdate 43 include dos h include graphics h definePATH c tc voidmain structdate dp sysdate 定义结构体变量 structtime tp systime unsignedchart intgd VGA gm VGAHI size charch 20 p initgraph 44 tp 更新t 45 11 7用指针处理链表1 链表概述1 动态数据结构概念数组和结构体是定长数据结构 而链表 堆栈 队列 树 图等是执行时大小可变的动态数据结构 链表是连成一行的数据项集合 每一个数据项 元素 称为节点 可以在链表中的任意位置进行节点插入或删除操作 使链表数据项的个数随之增加或减少 46 2 链表的构成单向链表图示 104813701012头节点表内节点尾节点 head 其中 各节点是相同的结构体类型 该类型有三个成员 head是指针变量 存放链表的头节点指针1048 各节点应包含一个指针成员存放下一节点的地址 各节点存储有可能不连续 但各节点逻辑上连续 47 3 节点的构成上图每个节点具有如下结构体类型 structstudent longnum floatscore structerstudent next 链节成员 其中 成员num score用于存放一个节点的具体数据 成员next是指针类型 用于存放下一节点指针 最后一个节点的next成员存放空指针NULL 成员next是指向与自身同一类型的结构 这种结构称为自引用结构 只有指针成员可自引用 节点是在运行时动态生成的 48 4 动态内存分配和释放建立和维护动态数据结构需要实现动态内存分配 如在链表中插入节点需要先申请一段存储区域 而删除一个节点需要释放该节点原先占用的存储区域 这可由标准函数实现 内存分配函数原形 void malloc unsignedsize 功能 申请长度为size个字节的内存空间 若申请成功 返回存储块起始指针 该指针类型为void 否则返回空指针 NULL 内存释放函数原形 voidfree void p 功能 释放p所指向的内存块 包含文件 malloc h stdlib h中均有其原型声明 49 5 采用链表的意义 与定长数据结构数组相比 链表能更好地利用内存 按需分配和释放存储空间 在链表中插入或删除一个节点 只需改变某节点 链节 成员的指向 而不需要移动其它节点 相对数组元素的插入和删除效率高 即 链表特别适合于对大线性表频繁插入和删除元素 或成员数目不定的数据结构 50 6 链表的类型单链表 每个节点只有一个指向后继节点的指针双向链表 每个节点有两个用于指向其它节点的指针 一个指向前趋节点 一个指向后继节点循环链表 使最后一个节点的指针指向第一个节点 51 2 单链表的建立和输出建立链表的准备工作 1 定义链表的节点类型 2 定义与节点同类型的链表头指针变量head并赋值0 表示链表在建立之前是空的 3 定义与节点同类型的工作指针变量p1 p2 52 建立链表的步骤 1 开辟第一个节点的存储区域 使head p1 p2指向第一个节点 并输入第一个节点数据 head p2 操作 len sizeof structstudent p1 structstudent malloc len scanf ld f 53 2 开辟下一节点的存储区域 使p1指向新节点 输入新节点数据 并将上一个节点的next成员指向新节点 head p1 1048 操作 p1 structstudent malloc len scanf ld f 使p2也指向新节点 1370 1370 54 3 重复第2步 建立并链接多个节点直至所需长度 将末尾节点的next成员赋值0 head p2 NULL 10481370 操作 p1 structstudent malloc len scanf ld f 末尾节点next赋值0 55 例 建立并输出有3名学生数据的单链表 include 包含NULL的定义 include defineN3structstudent 结构体类型定义 longnum floatscore structstudent next 自引用结构体指针 voidmain 56 voidmain structstudent head p1 p2 inti len sqrt 5 5 TC激活浮点运算 head NULL head不指向任何位置 len sizeof structstudent 求类型长 for i 1 inum 标记末尾节点 57 voidmain for i 1 inext p1指向下一节点 printf d num ld score 5 2f n i p1 num p1 score main 58 例 将上题利用函数实现 并求平均成绩 定义如下函数 建立链表函数 structstudent create void 输出链表函数 voidplink structstudent head 求平均值函数 floataverf structstudent head 函数间信息传递 主函数 create plink averf 无参 头指针 头指针 无返回值 平均值 头指针 59 include include defineN3structstudent 全局结构类型 longnum floatscore structstudent next voidmain 60 voidmain structstudent head create void voidplink structstudent head floataverf structstudent head inti len floataver sqrt 5 5 clrscr TC中使用head NULL head create 返回链表头指针 plink head aver averf head 返回平均值 printf Average 5 2f n aver 61 structstudent create structstudent head p1 p2 inti len len sizeof structstudent for i 1 inum 返回链表头指针 62 voidplink structstudent head 输出各节点 structstduent p inti for i 1 inext printf d num ld score 5 2f n i p num p score return P P 63 floataverf structstudent head structstudent p floatsum 0 intc 0 p head 使p指向首节点 while p NULL c c统计节点数 sum sum p score p p next return sum c 返回平均值 64 1370 3 节点的删除步骤 从头节点开始按查找关键字查找要删除的节点 2 找到 则将要删除节点的 链节 成员赋给前一节点的 链节 成员 使删除的节点脱离链表 若 要删除节点为首节点 则将首节点 链节 成员赋给链头指针变量 3 释放已被删除节点占用的空间 10481012 head p NULL 1048 1012 65 例 按上例删除指定学号的节点structstudent del structstudent head longn structstudent p1 p2 n 要删除学号 p1 head if p1 num n head p1 next 删除首节点 else do p2 p1 p1 p1 next 继续找 while p1 NULL 返回头指针 66 voidplink structstudent head 更具通用性 structstudent p p head while p NULL printf num ld score 5 2f n p num p score p p next return 注 本形式的链表输出函数具有通用性 可适应由于删除或插入节点引起的链表长度的变化 67 4 节点的插入插入可分为随意插入和按顺序插入 随意插入包括插入到头部 尾部或中间指定位置 按顺序插入是指按某关键字的顺序插入 而在插入前链表必须已按该关键字进行了排序 按顺序插入的步骤 开辟待插入节点的存储区域并输入数据 2 查找插入位置 从链表首节点开始按关键字成员与待插入节点相同成员进行比较 直到确定了插入位置 68 3 将插入位置前一节点的 链节 成员赋给待插入节点的 链节 成员 若 插入点在链头 则将头指针赋给待插入节点的 链节 成员 4 将待插入节点的指针赋给前一节点 链节 成员 若 插入点在链头 先将头指针赋给插入节点的指针域 再将待插入节点的指针赋给头指针变量 head 1048 104813701012 1012 2680 2680 69 例 按上例在链表中按学号顺序插入节点插入函数 structstudent insert structstudent head structstudent p0 p1 p2 longn intlen len sizeof structstudent p0 structstudent malloc len 申请新节点 printf Enternum scoretoinsert scanf ld f 从首节点开始查找 70 p1 head 插入在头部 if nnum p0 next head head p0 else do 查找插入位置 p2 p1 p1 p1 next while p1 NULL insert 71 例 编写一个通用的函数 可根据需要建立任意节点数的链表 structstudent creat 无参有返回值 structstudent head NULL p1 p2 intlen longn floats len sizeof structstudent while 1 循环次数不确定 printf Enternumber score scanf ld f 72 while 1 printf Enternumber score scanf ld f 返回链表头指针 creat 73 补充作业 实验 JOBBCB1 C 用随机数建立10节点有序链表 提示 边生成随机数边建立节点 并判断新节点应插入的位置 JOBBCB2 C 10只猴子围成一圈选猴王 方法是1 2 3报数 数到第3者退出 用循环链表模拟 注意 链头指针 最后一个节点链节成员指向头节点 74 11 10用typedef定义类型的别名关键字typedef可用来为类型标识符建立一个别名 这个别名同样可用于变量 数组 函数等对象的声明 使用一般形式 typedef原类型名新类型名 其中 原类型名可以是标准的或用户定义的 新类型名即为别名 别名通常大写 意义 1 用较短的别名代替用户定义的结构体类型名 2 使程序具有更好的通用性 75 如 typedeffloatREAL 定义类型别名 REALx y 用类型别名定义变量 如 typedefunsignedlongULONG ULONGa b 如 typedefstruct longnum charname 20 floagscore 4 STRSTU 结构体类型的别名 STRSTUs1 s2 stu 10 定义变量 数组 voidfun1 STRSTU 声明函数 76 TurboC对文件类型FILE的定义 typedefstruct shortlevel fill emptylevelofbuffer unsignedflags Filestatusflags charfd Filedescriptor unsignedcharhold Ungetccharifnobuffer shortbsize Buffersize unsignedchar buffer Datatransferbuffer unsignedchar curp Currentactivepointer unsignedistemp Temporaryfileindicator shorttoken Usedforvaliditychecking FILE ThisistheFILEobject 77 VisaulC在stdio h中对文件类型FILE的定义 struct iobuf char ptr int cnt char base int flag int file int charbuf int bufsiz 缓冲区尺寸char
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高速养护施工方案(3篇)
- 新店开业当天活动策划方案(3篇)
- 信号总线施工方案(3篇)
- 高级执法考试题库及答案
- 征兵工作教学课件
- 北京市门头沟区2023-2024学年八年级下学期期末质量监测物理题目及答案
- 写高三数学题目及答案
- 小学智力测试题目及答案
- 高二物理《浮力原理的应用:高中物理实验教程》
- 市场资源置换合作合同
- 地方政府债务和隐性债务口径及认定标准
- 气排球工会活动方案
- 2025内蒙古巴彦淖尔市能源(集团)有限公司招聘48人笔试参考题库附带答案详解
- 鉴别茅台培训课件图片
- 会议管理实务培训课件
- 甘肃省陇南市成县县属国有企业招聘笔试题库2025
- dcs权限管理制度
- 2025年陕西山西青海宁夏高考历史试卷真题答案详解(课件)
- 2025年广西专业技术人员继续教育公需科目(二)答案
- 护理学解剖课件
- 患者信息安全课件
评论
0/150
提交评论