




已阅读5页,还剩41页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章 结构体与联合体,8.1 程序与程序文件 8.2 结构体数组 8.3 结构体与指针 8.4 链 表 8.5 联 合 体 8.6 枚举类型与自定义类型名 8.7 程序举例,8.1 程序与程序文件 8.1.1 结构体类型变量的定义 定义结构类型变量包括两个方面:首先要定义结构体类型,以便确定该类型中有哪些成员,各成员属于什么数据类型;然后再定义属于该结构体类型的变量。,返回目录,1定义结构体类型 定义结构体类型的一般形式如下: struct 结构体类型名 成员表; 其中在“成员表”中定义了该类型中有哪些成员,各成员属于什么数据类型。,2定义结构体类型变量 定义结构体类型变量的一般形式为 struct 结构体类型名 变量表; 定义结构体类型与定义结构体类型变量是分开说明的。C语言还允许在定义结构体类型的同时定义结构体类型变量。其形式为 struct 结构体类型名 成员表 变量表;,如果在函数体外定义了一个结构体类型,则从定义位置开始到整个程序文件结束之间的所有函数中均可定义该类型的变量;但在函数体内所定义的结构体类型,只能在该函数体内能定义该类型的变量。即结构体类型的定义与普通变量定义的作用域是相同的。,8.1.2 结构体类型变量的引用 在程序中定义了某结构体类型的变量后就可以被引用。 结构体变量的一般引用方式如下: 结构体变量名.成员名 其中“.”为结构体成员运算符,它的优先级最高。,8.1.3 结构体的嵌套 C语言规定,结构体类型的定义可以嵌套。,8.1.4 结构体类型变量的初始化 与普通变量一样,在定义结构体类型变量的同时也可以对结构体类型变量赋初值。但C语言规定,只能对全局的或静态的局部结构体类型变量进行初始化。为了将结构体类型变量定义为静态存储类型,在定义时应加上static关键字。但是,目前在大部分计算机系统中,对结构体类型变量初始化时不必加static关键字,其原理与普通数组的初始化一样。,8.1.5 结构体与函数 1结构体类型变量的成员作为函数参数 与数组元素可以作为函数参数一样,结构体类型变量中的成员也可以作为函数参数。在这种情况下,在被调用函数中的形参是一般变量,而调用函数中的实参是结构体类型变量中的一个成员,但要求它们的类型应一致。,2结构体类型变量作为函数参数 与一般变量可以作为函数参数一样,结构体类型的变量也可以作为函数参数。在这种情况下,在被调用函数中的形参是结构体类型的变量,调用函数中的实参也是结构体类型的变量,但要求它们属于同一个结构体类型。,3结构体类型的函数 与定义标准数据类型函数一样,C语言也允许定义结构体类型的函数。结构体类型函数的返回值是结构体类型的数据。,8.2 结构体数组 8.2.1 结构体数组的定义与引用 与整型数组、实型数组、字符型数组一样,在程序中也可以定义结构体类型的数组。但C语言规定,同一个结构体数组中的元素应为同一种结构体类型。,返回目录,例如, struct student int num; char name10; char sex; int age; float score3; stu10; 定义了“学生情况”型的一个数组stu,可存放10个学生的情况。每一个学生的情况包括:学号(num)、姓名(name10)、性别(sex)、年龄(age)、3个成绩(score3)。实际上,定义了该数组后,相当于开辟了一个如表8.1所示的表格空间。,表8.1 学生情况型的数组表格空间,8.2.2 结构体数组作为函数参数 与普通数组一样,结构体类型数组也能作为函数参数,并且形参与实参结合的方式完全一样。如果在被调用函数中改变了结构体类型形参数组元素中各成员值,实际上也就改变了结构体类型实参数组元素中的各成员值。因为结构体类型形参数组与结构体类型实参数组是同一个存储空间。,8.3 结构体与指针,8.3.1 结构体类型指针变量的定义与引用 结构体类型的指针变量指向结构体类型变量或数组(或数组元素)的起始地址。 例如, struct student int num; char name10; char sex; int age; float score; ; struct student st1, st2, st10, *p; 其中定义了一个指向结构体“学生情况”型的指针p。,返回目录,由上所述,当结构体类型的指针变量p指向一个结构体类型变量后,下列3种表示是等价的: 结构体变量名.成员 (*p).成员 p成员 它们都表示结构体变量中的一个成员。,8.3.2 结构体类型指针作为函数参数 结构体类型指针可以指向结构体类型的变量,因此,当形参是结构体类型指针变量时,实参也可以是结构体类型指针(即地址)。在结构体类型指针作为函数参数的情况下,由于传送的是地址,因此,如果在被调用函数中改变了结构体类型形参指针所指向的地址中的值,实际上也就改变了结构体类型实参指针所指向的地址中的值。,例8.7 用结构体类型指针作为函数参数。 在下面的程序中,主函数的功能是定义了一个结构体student型的变量st,同时为之初始化,然后输出变量st中各成员的值,将结构体类型变量st的地址(即&st)作为实参调用函数chang()后再输出变量st中各成员的值;函数chang()的功能是修改结构体类型形参指针t所指向的结构体类型数据中成员tscore的值,并输出修改前后结构体类型指针所指向的数据中各成员的值。,#include “stdio.h“ struct student int num; char name10; char sex; int age; float score; ; void chang(t) struct student *t; printf(“t%6d%8s%3c%4d%7.2fn“, tnum,tname,tsex,tage,tscore); tscore95.0; printf(“t%6d%8s%3c%4d%7.2fn“, tnum,tname,tsex,tage,tscore); ,main() static struct student st101,“Zhang“,M,19,89.0; printf(“st%6d%8s%3c%4d%7.2fn“, st.num,,st.sex,st.age,st.score); chang(&st); printf(“st%6d%8s%3c%4d%7.2fn“, st.num,,st.sex,st.age,st.score); ,结构体类型指针也可以指向数组或数组元素,因此,当形参是结构体类型指针变量时,实参也可以是结构体类型数组名或数组元素的地址。 与标准数据类型的数组与指针一样,在结构体类型数组指针作函数参数时,也可以有以下4种情况: (1)实参与形参都用结构体类型数组名; (2)实参用结构体类型数组名,形参用结构体类型指针变量; (3)实参与形参都用结构体类型指针变量; (4)实参用结构体类型指针变量,形参用结构体类型数组名。,8.4 链 表,8.4.1 链表的基本概念 1链表的一般结构 链表由结点元素组成。为了适应链表的存储结构,计算机存储空间被划分为一个一个小块,每一小块占若干字节,通常称这些小块为存储结点。 将存储空间中的每一个存储结点分为两部分:一部分用于存储数据元素的值,称为数据域;另一部分用于存放下一个数据元素的存储序号(即存储结点的地址),称为指针域。,返回目录,每一个结点的结构如图8.1所示。,图8.1 链表的结点结构,在链表中,用一个专门的指针HEAD指向链表中第一个数据元素的结点(即存放第一个数据元素的存储结点的序号)。链表中最后一个元素后面已没有结点元素,因此,链表中最后一个结点的指针域为空(用NULL或0表示),表示链表终止。链表的逻辑结构如图8.2所示。,图8.2 链表的逻辑结构,2结点结构体类型的定义 在C语言中,定义链表结点结构的一般形式如下: struct 结构体名 数据成员表; struct 结构体名 *指针变量名; ;,3结点的动态分配 在C语言中,可以利用 malloc 函数向系统申请分配链表结点的存储空间,其形式为 malloc(存储区字节数) 该函数返回存储区的首地址。例如, struct node int d; struct node *next; ; struct node *p; p(struct node * )malloc(sizeof(struct node); 释放存储区用如下函数: free(p);,8.4.2 链表的基本运算 1在链表中查找指定元素 在对链表进行插入或删除的运算中,总是首先需要找到插入或删除的位置,这就需要对链表进行扫描查找,在链表中寻找包含指定元素值的前一个结点。当找到包含指定元素的前一个结点后,就可以在该结点后插入新结点或删除该结点后的一个结点。,下面是在非空链表中寻找包含指定元素值的前一个结点的C语言描述。 struct node /*定义结点类型*/ ET d; /*ET为数据元素类型名,下同*/ struct node *next; ; /*在头指针为head的非空链表中寻找包含元素x的前一个结点p(结点p作为函数值返回)*/ struct node *lookst(head,x) ET x; struct node *head; struct node *p; phead; while(pnext!NULL)&(pnext)d)!x) ppnext; return(p); ,2链表的插入 链表的插入是指在原链表中的指定元素之前插入一个新元素。 要在链表中包含元素x的结点之前插入一个新元素b。其插入过程如下: (1)用malloc()函数申请取得新结点p,并置该结点的数据域为b。即令pdb。 (2)在链表中寻找包含元素x的前一个结点,设该结点的存储地址为q。链表如图8.3(b)所示。 (3)最后将结点p插入到结点q之后。为了实现这一步,只要改变以下两个结点的指针域内容:, 使结点p指向包含元素x的结点(即结点q的后件结点),即令 pnextqnext 使结点q的指针域内容改为指向结点p,即令 qnextp,图8.3 链表的插入,3链表的删除 链表的删除是指在链表中删除包含指定元素的结点。 为了在链表中删除包含指定元素的结点,首先要在链表中找到这个结点,然后将要删除结点放回到可利用栈。 要在链表中删除包含元素x的结点。其删除过程如下: (1)在链表中寻找包含元素x的前一个结点,设该结点地址为q。则包含元素x的结点地址pqnext。 (2)将结点q后的结点p从链表中删除,即让结点q的指针指向包含元素x的结点p的指针指向的结点,即令 qnextpnext (3)将包含元素x的结点p释放。此时,链表的删除运算完成。,图8.4 链表的删除,8.5 联 合 体,C语言中中的联合数据类型可以满足这种需要。联合体又称为共用体,意为各种不同数据共用同一段存储空间。 与结构体类似,为了定义联合体类型变量,首先要定义联合体类型,说明该联合体类型中包括哪些成员,它们各属于何数据类型,然后再定义该类型的变量。,返回目录,定义联合体数据类型的一般形式为 union 联合体名 成员表 ; 例如, union w int k; double d; char c; ; 定义了一个联合体类型w,包括代表整型量的成员k、代表双精度型量的成员d和代表字符型量的成员c。,下面对联合体类型变量作几点说明: (1)由于一个联合体变量中的各成员共用一段存储空间,因此,在任一时刻,只能有一种类型的数据存放在该变量中,即在任一时刻,只有一个成员的数据有意义,其他成员的数据是没有意义的。 (2)在引用联合体变量中的成员时,必须保证数据的一致。 (3)在定义联合体变量时不能为其初始化,并且,联合体变量不能作为函数参数。 (4)联合体类型与结构体类型可以互相嵌套,即联合体类型可以作为结构体类型的成员,结构体类型也可以作为联合体类型的成员。,8.6 枚举类型与自定义类型名 8.6.1 枚举类型 (1)先定义枚举类型,然后定义该枚举类型的变量。 定义枚举类型的一般形式为 enum 枚举类型名 枚举元素列表 ; 其中在枚举元素列表中依次列出了该类型中所有的元素(即枚举常量),如果在定义中没有显式地给出这些元素的值,这些元素依次取值为0,1,2,。 (2)在定义枚举类型的同时定义该枚举类型的变量。 这种定义方法的一般形式为 enum 枚举类型名 枚举元素列表 变量表; (3)直接定义枚举类型变量。 这种定义方法的一般形式为 enum 枚举元素列表 变量表;,返回目录,在使用枚举类型数据时,要注意以下几个问题: (1)不能对枚举元素赋值,因为枚举元素本身就是常量(即枚举常量)。 (2)虽然在程序中不能对枚举元素赋值,但实际上,每个枚举元素都有一个确定的整型值。 (3)C语言允许将一个整型值经强制类型转换后赋给枚举类型变量。,8.6.2 自定义类型名 在一个C程序中,可以使用C提供的标准数据类型名(如int,char,float,double等),也可以使用用户自己定义的数据类型名(如结构体类型,联合体类型,枚举类型等)。除此之外,C语言还允许用typedef声明新的类型名来代表已有的类型名,称为自定义类型名。 自定义类型名的一般形式为 typedef 原类型名 新类型名; 它指定用新类型名代表原类型名。,8.7 程序举例,例8.11 设有学生情况登记表如表8.3所示。用选择排序法对该表按成绩从小到大进行排序。 表8.3 学生情况登记表,返回目录,其C程序如下: #define STUDENT struct student STUDENT int num; char name8; char sex; int age; double score; ; #include “stdio.h“ main() int i; void sort();,static STUDENT stu10101,“Zhang“,M,19,95.6, 102,“Wang“,F,18,92.4, 103,“Zhao“,M,19,85.7, 104,“Li“,M,20,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年自考专业(小学教育)测试卷附参考答案(基础题)
- 2025年期货从业资格之《期货法律法规》考前冲刺测试卷包及参考答案详解(黄金题型)
- 2025年法院司法辅助人员模拟题库附参考答案详解【轻巧夺冠】
- 农发行昭通市威信县2025秋招笔试综合模拟题库及答案
- 农发行南阳市社旗县2025秋招群面模拟题及高分话术
- 农发行娄底市新化县2025秋招数据分析师笔试题及答案
- 紫金县2025广东河源紫金县残疾人康复中心招聘编外人员1人笔试历年参考题库附带答案详解
- 职业技能培训企业实践报告
- 心理健康促进管理规定报告制定
- 创新交流规定制度
- 专题训练基本不等式求最值(原卷版)
- 2025至2030MCU行业市场发展分析及竞争形势与投资机会报告
- 2025年1月浙江省普通高校招生选考科目高考英语真题试卷(浙江卷 含答案)
- 2025年全国保密教育线上培训考试试题库附答案(完整版)含答案详解
- 国企职工劳务合同协议
- GB/T 37507-2025项目、项目群和项目组合管理项目管理指南
- 商品检验试题及答案
- 骨科危重患者的急救及护理
- 防水工程质量保证书
- 大额资金使用管理办法
- 2025年邮政社招笔试试题及答案
评论
0/150
提交评论