结构体、枚举和共用体类型.ppt

上传人:max****ui 文档编号:8601220 上传时间:2020-03-30 格式:PPT 页数:72 大小:198KB
返回 下载 相关 举报
结构体、枚举和共用体类型.ppt_第1页
第1页 / 共72页
结构体、枚举和共用体类型.ppt_第2页
第2页 / 共72页
结构体、枚举和共用体类型.ppt_第3页
第3页 / 共72页
点击查看更多>>
资源描述
第8章结构体 枚举和共用体类型 10 1结构体类型10 2结构体和函数10 3动态数据结构 链表10 4枚举类型10 5共用体类型10 6用户自定义类型 10 1结构体类型 结构体类型的定义结构体类型中可以根据需要包含若干相同或不同类型的成员 这些成员所代表的信息必须是相关的信息 结构体类型定义的格式为 struct结构体名 类型名成员名1 类型名成员名2 类型名成员名n 例如 structdate intyear intmonth intday 10 1结构体类型 structstudent intnumber 学号 charname 8 姓名 charsex 性别 floatscore 4 成绩 struct是结构体类型的标识 是关键字 struct和后面的结构体名共同构成结构体类型名 结构体名应符合标识符的命名规则 结构体所有成员的定义用花括弧括起来 结构体成员的定义方式和变量的定义方式一样 成员类型可以是基本类型的 也可以是构造类型的 各成员之间用分号分隔 结构体内的各个成员名不能重名 但成员名可以与结构体外其他标识符同名 并不产生冲突 10 1结构体类型 结构体变量的定义用已经定义的结构体类型定义结构体变量 structstudentstu 定义结构体类型的同时定义结构体变量 stu1 stu2 structstudent intnumber 学号 charname 8 姓名 charsex 性别 floatscore 4 成绩 stu1 stu2 10 1结构体类型 定义无名结构体类型的同时定义结构体变量 这种定义形式省略了结构体名 不再需要定义此种类型变量的情况才可采用这种方式 struct intnumber 学号 charname 8 姓名 charsex 性别 floatscore 4 成绩 stu结构体变量各个成员按照定义的顺序依次占用连续的空间 可以定义指针变量指向结构体类型变量 结构体变量的地址虽与其第一个成员的地址的值是相同的 但它们的类型是不同的 它们之间不能直接相互赋值 但是可以先将其用强制类型转换 转换为同一类型指针后相互赋值 10 1结构体类型 结构体变量的初始化和引用结构体变量的初始化若在定义之后进行初始化操作 只能对每个成员单独进行赋值 若在定义变量的同时进行初始化 则用一对花括弧括起各个成员值的列表并用赋值号和变量连接 成员值之间逗号分隔 具体格式为 结构体类型名结构体变量 成员值列表 例如 structstudentstu 1001 wang f 60 5 80 75 90 结构体变量的引用只能引用结构体变量的成员 不能引用整个结构体变量 结构体变量的成员引用形式为 结构体变量名 成员名其中 称为成员运算符 如果是通过指向结构体变量的指针引用结构体成员 形式为 指针变量名 成员名或指针变量名 成员名 10 1结构体类型 如果结构体的成员仍然是构造类型 则需要逐级引用 直至最低级的成员 即只能对结构体变量最低级的成员进行存取和运算 例10 1 输入学生的各项信息 计算总分和平均成绩后输出 include stdio h structdate intyear intmonth intday 定义结构体类型structdate structstudent intnumber 学号 charname 10 姓名 structdatebirthday 生日 structdate类型 10 1结构体类型 floatscore 4 四门课成绩 floattotal 总分 floatave 平均成绩 定义结构体类型structstudent main structstudentstu p intk printf pleaseenternumber 10 1结构体类型 for stu total 0 k 0 knumber printf name s n p name printf birthday d d d n p birthday year p birthday month p birthday day printf score for k 0 kscore k printf ntotal 6 2f n stu total 10 1结构体类型 printf average 6 2f n stu ave 某次程序运行结果为 pleaseenternumber name 1002li pleaseenterbirthday year month day 197568 pleaseenterthescore 4 8078 59283 5 number 1002name libirthday 1975 6 8score 80 0078 5092 0083 50total 334 00average 83 50 10 1结构体类型 结构体数组结构体数组的定义 初始化若数组元素的类型为结构体类型 数组为结构体数组 定义结构体数组的同时也可对数组进行初始化操作 例如 structstudent intnumber 学号 charname 10 姓名 floatscore 4 四门课程成绩 floattotal 总分 floatave 平均成绩 stu 3 461 liu 80 78 67 80 0 0 032 geng 98 78 86 90 0 0 103 qian 79 89 68 80 0 0 可以定义指向结构体数组元素的指针变量 然后通过指针对数组元素操作 10 1结构体类型 结构体数组的引用结构体数组元素也是通过数组名和下标来引用 但要注意只能对最低级的成员进行存取和运算 引用的一般形式为 数组名 下标 成员名例如 stu 1 number stu 0 score 2 stu 2 ave通过指针引用结构体数组元素的形式和通过指针引用结构变量形式一样 为 指针变量名 成员名或指针变量名 成员名例如 语句 p 10 1结构体类型 例10 2 计算某班期末考试中所有学生的总分和平均成绩 defineN50 include stdio h structstudent intnumber 学号 charname 10 姓名 floatscore 4 四门课程成绩 floattotal 总分 floatave 平均成绩 main structstudentstu N p inti k for i 0 p stu p stu N p i 输入学生的信息 printf the dstudent n i printf number 10 1结构体类型 scanf d s 10 2结构体和函数 结构体变量的成员作为函数参数结构体变量的成员可作为函数的实际参数 但是不适合作函数的形式参数 结构体变量的成员作函数实参的用法与普通变量作函数实参的用法相同 形参与实参之间仍然是 值传递 的方式 例10 3 重新编写例10 2 defineN50 include stdio h structstudent intnumber 学号 charname 10 姓名 floatscore 4 四门课程成绩 floattotal 总分 floatave 平均成绩 10 2结构体和函数 floattotal floats intn 计算总成绩 intk floatsum 0 for k 0 k n k sum s k return sum floataverage floatx intn return x n 返回平均值 main structstudentstu N inti k for i 0 i N i 输入学生的信息 printf the dstudent n i printf number 10 2结构体和函数 scanf d s 10 2结构体和函数 结构体指针变量作为函数参数允许函数之间传递结构体变量 若形参是结构体变量 那么实参也应是同类型的结构体 被调用函数对形参结构体变量的修改不能传递给实参 形参结构体变量占用内存空间 接收实参数据带来空间和时间的巨大开销 因此语法上虽然允许 但一般很少采用这种方式 若向函数传递结构体变量的地址 则可以通过指针对实参结构体变量的空间操作 从而改变实参的值 参数传递时只需传递一个地址 空间和时间的代价都很小 一般采用结构体指针作为函数参数 而不采用结构体变量作为函数参数 10 2结构体和函数 例10 4 重新编写例10 3 defineN50 include stdio h structstudent intnumber 学号 charname 10 姓名 floatscore 4 四门课程成绩 floattotal 总分 floatave 平均成绩 voidinput structstudent stu 输入学生信息 intk printf number 10 2结构体和函数 for k 0 kscore k voidtotal average structstudent stu 计算总成绩和平均值 intk stu total 0 for k 0 ktotal stu score k stu ave stu total 4 voidoutput structstudent stu 输出学生信息 intk printf number 6d n stu number printf name s n stu name printf score 10 2结构体和函数 for k 0 kscore k printf ntotal 10 2faverage 10 2f n stu total stu ave main structstudentstu N p inti for i 0 i N i 输入学生的信息 printf the dstudent n i input 10 2结构体和函数 结构体数组作函数参数向函数传递结构体数组实际也是传递数组的首地址 形参数组与实参数组使用共同的内存单元 函数形参 实数是同类型的结构体数组名或结构体指针 例10 5 重新编写例10 4 defineN50 include stdio h structstudent intnumber 学号 charname 10 姓名 floatscore 4 四门课程成绩 floattotal 总分 floatave 平均成绩 10 2结构体和函数 voidinput structstudentstu intn 输入学生的信息 inti k for i 0 i n i printf the dstudent n i printf number 10 2结构体和函数 for stutotal 0 for k 0 ktotal stu score k stu ave stu total 4 voidoutput structstudent stu intn 输出处理后的学生信息 intk i for i 0 inumber printf name s n stu i name printf score 10 2结构体和函数 for k 0 kscore k printf ntotal 10 2faverage 10 2f n stu i total stu i ave main structstudentstu N structstudent q stu input q N total average stu N output stu N 10 3动态数据结构 链表 内存空间的动态分配和释放free函数free函数的的格式 voidfree void p free函数的功能 释放指针变量p所指向的内存区 该函数没有返回值 一般p的值是调用malloc函数或calloc函数的返回值 malloc函数malloc函数的格式 void malloc unsignedintsize malloc函数的功能 在内存的动态存储区中分配size个字节的连续空间 并返回分配空间的起始地址 若分配失败 则返回空指针 注意 malloc函数的返回值一般是空类型的指针 有的编译系统将其处理成char类型的指针 使用该函数时通常需要用强制类型转换 将其转换为所需要的类型 10 3动态数据结构 链表 例10 6 注意内存空间的分配和释放 main double pointer pointer double malloc sizeof double 申请一个double类型变量所需内存空间 pointer 8 234 printf 6 4f n pointer pointer pointer 10 printf 7 4f n pointer pointer pointer 2 printf 6 4f pointer free pointer 释放空间 10 3动态数据结构 链表 程序运行结果为 8 234018 23409 1170calloc函数calloc函数的的格式 void calloc unsignedintn unsignedintsize calloc函数的功能 分配内存的动态存储区中n个长度为size个字节的连续空间 并返回分配空间的起始地址 若分配失败 则返回一个空指针 对calloc的返回值同样也可进行强制类型转换后使用 注意 calloc函数常用来为一维数组分配空间 其中n表示数组的长度 size表示数组元素所占字节数 这种方式获得的数组一般称为动态数组 10 3动态数据结构 链表 例10 7 注意内存空间的分配和释放 main int a i a int calloc 5 sizeof int 申请5个整型变量所需内存空间 for i 0 i 5 i a i i 1 for i 0 i 5 i printf 4d a i free a 释放空间 程序运行结果为 12345 10 3动态数据结构 链表 链表链表由若干个结点构成 一个结点就是一个结构类型的变量 链表的每个结点需要占用连续内存空间 但是整个链表无须占用连续空间 因此 结点成员应该包括两部分 一部分存放实际需要的数据信息 称为数据域 一部分存放指针 用来链接各个结点 称为链接域或指针域 在链表中 一个结点后面相邻的结点称为该结点的后继结点 该结点则称为其后继结点的前驱结点 单链表 结点指针域只包含一个后继结点地址的链表 用一个指针变量保存单链表的首地址 即第一个结点的地址 这个指针变量被称为头指针 头指针是一个链表的标志 注意 在链表的定义中 指向前驱结点或后继结点的指针的基类型是结点自身类型 例10 8 通过给结点的指针域赋值建立一个单链表 include stdio h structnode charc structnode next main structnode n1 n2 n3 head p 申请三个结点空间 n1 structnode malloc sizeof structnode n2 structnode malloc sizeof structnode n3 structnode malloc sizeof structnode 建立链表 head n1 10 3动态数据结构 链表 10 3动态数据结构 链表 n1 c A n1 next n2 n2 c B n2 next n3 n3 c C n3 next NULL for p head p NULL p p next printf 3c p c 10 3动态数据结构 链表 链表的基本操作为了简化链表的各种操作 一般在含有有效信息的所有结点之前再附加一个数据域不包含任何信息的结点 这个结点被称为 头结点 头结点的存在是以一个结点空间为代价换取程序编写的简单明了 下面的各项链表操作都是针对有头结点的链表编写的 结点的类型均为 structnode intdata structnode next 并假定成员data的值不可能为负数 10 3动态数据结构 链表 创建链表采用从表尾插入新结点的方式 则创建链表的主要步骤为 生成只含有头结点的空链表 头指针head和尾指针tail 指向链表的最后一个结点 均指向头结点 读取数据信息 申请新的结点空间 将数据存于新结点 将新结点插入到链表最后一个结点的后面 tail指针指向新插入的结点 重复 的操作直到输入结束 尾结点指针域赋NULL 例10 9 编写函数 在表尾插入结点生成单链表 structnode createtail structnode head p tail intdata head structnode malloc sizeof structnode 生成头结点 tail head 尾指针指向最后一个结点 scanf d 读取数据 10 3动态数据结构 链表 while data 0 p structnode malloc sizeof structnode 生成新结点p p data data 读入的数据存放到结点p的数据域 tail next p 将新结点p插入到表尾 tail p 修改尾指针tail指向当前的尾结点 scanf d 返回头指针 10 3动态数据结构 链表 10 3动态数据结构 链表 10 3动态数据结构 链表 若采用从表头插入新结点的方式 则创建链表的主要步骤为 生成只含有头结点的空链表 定义头指针head指向头结点 读取数据信息 申请新的结点空间 将数据存于新结点 将新结点插入到头结点后面 重复 的操作直到输入结束 例10 10 编写函数 在表头插入结点生成单链表 structnode createhead structnode head p intdata head structnode malloc sizeof structnode 生成头结点 head next NULL 置为空表 scanf d 读入的数据存放到结点p的数据域 10 3动态数据结构 链表 p next head next 将新结点插入到头结点之后 head next p 修改头结点的指针域指向新插入结点 scanf d 返回头指针 10 3动态数据结构 链表 10 3动态数据结构 链表 例10 11 编写函数 输出单链表内容 voidoutput structnode head 输出链表 structnode p printf thelinklistis n p head next 指针变量p获得头结点后继结点的地址 while p NULL 判断指针变量p是否为NULL 为NULL表示链表结束 printf 6d p data 输出指针变量p结点的内容 p p next 指针变量p指向链表下一个结点 return 10 3动态数据结构 链表 删除结点在单链表中删除指定结点的主要步骤为 找到要删除的p结点和p结点的前驱结点q 由于单向链表有头结点 所以前驱结点一定存在 删除该结点 修改前驱结点的指针域指向待删除结点的后继结点 并释放被删除结点所占用的空间 注意 删除结点后 一定要释放被删除结点所占空间 否则 该结点会成为游离的 不可再用的空间 例10 13 编写函数 在单链表中删除值为x的结点 structnode delete structnode head intx 从链表中删除值为x的结点 structnode p q q head q指向头结点 p head next p指向第一个结点 while p 返回头指针 10 3动态数据结构 链表 10 3动态数据结构 链表 插入结点插入到p结点之后 相应C语句为 s next p next s的指针域指向p的后继结点 p next s p的指针域指向新插入结点s 10 3动态数据结构 链表 在结点p之前插入新结点 首先要找到p的前驱结点q 相应C语句为 s next p s的指针域指向p q next s q的指针域指向新插入结点s 10 3动态数据结构 链表 例10 14 编写函数 在单链表中值为x的结点之前插入一个值为y的结点 structnode insert structnode head intx inty 在链表值为x的结点前插入值为y的结点 structnode p q s s structnode malloc sizeof structnode 生成新结点s s data y 将y存放在新结点中 q head q指向头结点 p head next p指向第一个结点 while p data x 保持p指向当前结点 q指向p结点的前驱 10 3动态数据结构 链表 if p NULL 未找值为x的结点 返回空 printf notfindx n free s return head s next p 插入s结点到p之前 q next s return head 返回头指针 10 3动态数据结构 链表 例10 15 链表的综合操作 inlude data h inlude func c inlude stdio h main structnode head p intx a b charch do printf n1 create n2 search n3 insert n4 delete n5 output n0 exit n printf pleaseselect ch getch while ch 0 ch getch 输入不在0到5之间无效 putchar ch printf n 10 3动态数据结构 链表 switch ch case 1 若选择1 创建链表 printf pleaseenterdata head createhead 创建链表 output head 输出创建后的链表 break case 2 若选择2 在链表中查找数据 printf pleaseenterdata scanf d 10 3动态数据结构 链表 case 3 若选择 在链表中插入数据 printf pleaseenterdata insertbbeforea a b scanf d d 10 3动态数据结构 链表 while ch 0 10 4枚举类型 枚举类型的定义枚举类型的定义格式如下 enum枚举类型名 枚举常量1 枚举常量2 枚举常量n enumweek Sunday Monday Tuesday Wednesday Thursday Friday Saturday enum是用来定义枚举类型的关键字 枚举类型名应符合标识符定义的规则 enum和枚举类型名共同构成枚举类型的类型名 花括弧内是该枚举类型所有可能的取值列表 也就是枚举常量列表 每个枚举常量都是有意义的标识符 枚举常量表面上是标识符 实际存储的是整型值 在系统默认情况下 第一个枚举常量的值是0 以后每个枚举常量的值是前一个常量的值加1 枚举常量的值在定义后不能被修改 枚举常量也可显示赋值 未被显式赋值的枚举常量的值是前一个常量值加1 enumweek Sunday 7 Monday 1 Tuesday Wednesday Thursday Friday Saturday 10 4枚举类型 枚举类型变量的定义和引用枚举类型变量的定义定义枚举类型的同时定义变量 enumcolors red blue green yellow c1 c2 20 先定义枚举类型 然后定义变量 enumcolors red blue green yellow enumcolorsc1 c2 20 如果之后不再使用此枚举类型 可定义类型时省略枚举类型名并同时定义变量 enum red blue green yellow c1 c2 20 枚举类型变量的引用枚举类型变量的取值范围只能是其枚举类型定义时所枚举的枚举常量 枚举常量可赋值给枚举变量 整型和枚举类型之间不能相互赋值 若要赋值 需进行强制类型转换 10 4枚举类型 例10 16 考虑程序执行结果 体会枚举类型的用法 main enumcolors red blue green yellow c1 c2 c1 blue c2 enumcolors 1 if c1 c2 printf yes elseprintf no 程序运行结果为 yes 10 4枚举类型 可以比较枚举类型变量的大小 枚举变量的比较相当于它们所隐含整数值的比较 枚举变量可以作为循环变量来控制循环 例10 17 考虑程序执行结果 体会枚举类型的用法 enumweek Sunday Monday Tuesday Wednesday Thursday Friday Saturday main enumweekw intk 0 for w Sunday w Saturday w k printf 2d k 程序运行结果为 0123456 10 4枚举类型 枚举类型变量无法直接读入 枚举类型直接输出也只是显示整数 而不能显示标识符形式的枚举常量 例10 18 仔细阅读下面例题 考虑程序执行结果 体会枚举类型的用法 enumweek sun mon tue wed thu fri sat main enumweekw m intday char name Sunday Monday Tuesday Wednesday Thursday Friday Saturday printf pleaseenterwhatdaytoday 0 sun 1 mon 2 tue 3 wed 4 thu 5 fri 6 sat scanf d 10 4枚举类型 for m w m w 6 7 m m 1 7 printf s name m 运行时输入4 程序运行结果为 pleaseenterwhatdaytoday 0 sun 1 mon 2 tue 3 wed 4 thu 5 fri 6 sat 4 ThursdayFridaySaturdaySundayMondayTuesday 10 5共用体类型 共用体类型的定义共用体类型定义的格式为 union共用体名 类型名成员名1 类型名成员名2 类型名成员名n union是关键字 标识共用体类型 共用体名应符合标识符的命名规则 union和共用体名共同构成共用体类型名 共用体的所有成员共占一段内存 某个时刻只有一个成员起作用 其它成员无效 整个共用体所占的内存大小等于占用内存单元最多的那个成员所占用的空间 花括弧中共用体成员定义和结构体成员定义方式相同 共用体类型的成员可以是构造类型 但通常情况下是基本类型的 10 5共用体类型 共用体变量的定义和引用变量的定义定义共用体类型的同时定义变量 先定义共用体类型 然后定义共用体变量 如果之后不再使用此共用体类型 可定义类型时省略共用体名并同时定义变量 unionexample charc1 intc2 floatc3 un1 un2 10 5共用体类型 unionexample charc1 intc2 floatc3 uinonexampleun1 un2 union charc1 intc2 floatc3 un1 un2 10 5共用体类型 变量的引用引用共用体变量时 一定要记住某一时刻只能有某一个成员起作用 只能引用共用体变量的成员 而不能引用整个共用体变量 引用形式为 共用体变量名 成员名un1 c1 un2 c2 un1 c3是合法的引用 可通过指向共用体的指针变量引用共用体变量 引用形式为 共用体指针变量 成员名或 共用体指针变量 成员名语句 unionun pu pu 之后 pu c pu k是合法的引用 说明 给共用体变量赋值时 只能对共用体的一个成员赋值 而不能对整个共用体变量赋值 对共用体变量而言 只有最近一次被赋值的成员是有效的 其他成员无效 10 5共用体类型 共用体变量不能在定义时初始化 若共用体的成员是构造类型的 则需要逐级引用至最低级的成员 共用体变量的地址和共用体各个成员的地址是相同的 但是它们的类型是不同的 例10 19 学校某个协会既有学生成员又有教师成员 学生信息包括姓名 年龄 职业 学生 S 和年级 教师信息包括姓名 年龄 职业 教师 T 和职称 输入协会成员列表 并输出年龄小于25岁的成员信息 10 5共用体类型 defineN5 include stdio h structassociator charname 10 姓名 intage 年龄 charjob 职业 union 年级 职称的公用体 intgrade charposition 10 category 10 5共用体类型 main structassociatormember N inti printf pleaseenterassociators nameagejobgrade position n for i 0 i N i 输入数据 scanf s d c member i name 10 5共用体类型 if member i job S printf d n member i category grade elseprintf s n member i category position 输入5条信息 运行结果为 pleaseenterassociators nameagejobgrade position li50Tprofessor wang33Tprofessor zhang24Tlector zhao21S3 liu26S1 associators age 25 zhang24Tlectorzhao21S3 10 6用户自定义类型 用typedef声明基本类型定义基本类型的新类型名的形式为 typedef基本类型名新类型名 例如 typedefcharCHARACTER CHARACTERch 80 c 用typedef声明构造类型数组类型的声明定义数组类型的新类型名的形式为 typedef新类型名 数组长度 例如 typedefcharSTRING 80 STRINGstr1 str2 10 6用户自定义类型 结构体 共用体类型的声明类型关键字 struct或union 类型名 类型名成员名1 类型名成员名2 类型名成员名n typedef类型关键字 struct或union 类型名新类型名 10 6用户自定义类型 例10 20 注意类型DATA使用 structdata intyear intmonth intday typedefstructdataDATA main DATAd d year 1990 d month 7 d day 9 printf year dmonth dday d d year d month d day 程序运行结果为 year 1990month 7day 9 10 6用户自定义类型 typedef类型关键字 struct或union 类型名 类型名成员名1 类型名成员名2 类型名成员名n 新类型名 typedefstructdata intyear intmonth intday DATA 10 6用户自定义类型 typedef类型关键字 struct或union 类型名成员名1 类型名成员名2 类型名成员名n 新类型名 10 6用户自定义类型 例10 21 注意类型TEST使用 typedefunion intx floaty TEST main TESTd d x 99 printf d d n d x d x 1 99 printf d f n d y 程序运行结果为 d 99d 1 990000 10 6用户自定义类型 枚举类型的声明enum枚举类型名 枚举常量列表 typedefenum枚举类型名新类型名 例如 enumcolors red blue green yellow typedefenumcolorsCOLOR typedefenum枚举类型名 枚举常量列表 新类型名 例如 typedefenumcolors red blue green yellow COLOR typedefenum 枚举常量列表 新类型名 例如 typedefenum red blue green yellow COLOR 用户自定义类型的用途减少书写工作量 增加程序可读性 提高程序的可移植性
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!