C语言讲义第07章-结构体与其他构造数据类型(原).ppt_第1页
C语言讲义第07章-结构体与其他构造数据类型(原).ppt_第2页
C语言讲义第07章-结构体与其他构造数据类型(原).ppt_第3页
C语言讲义第07章-结构体与其他构造数据类型(原).ppt_第4页
C语言讲义第07章-结构体与其他构造数据类型(原).ppt_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章 结构体与其他构造数据类型,C语言程序设计,主要内容,结构体 结构体数组的定义和引用 指向结构体的指针 结构体与函数 复杂的结构体 链表 共用体 位域 枚举类型 类型定义typedef 小结,7.1 结构体,表 71学生信息表,7.1 结构体,结构体类型的定义形式: struct 结构体类型名 数据类型 成员1; 数据类型 成员2; 数据类型 成员n; ;,7.1 结构体,例如:表7-1对应的结构体类型定义可以是: struct stu_info char no8; /*学号*/ char name10; /*姓名*/ char sex; /*性别*/ int age; /*年龄*/ char department20; /*院系*/ ;,7.1 结构体,结构体变量定义有以下三种形式: 先定义结构体类型,再定义结构体类型变量 例如:在结构体类型定义完成后,再定义变量。 struct stu_rec /* 定义学生记录结构体类型 */ char num8; /* 学号 */ char name10; /* 学生姓名 */ char sex; /* 性别 */ int score4; /* 四科考试成绩 */ ; struct stu_rec student1, student2; /*定义结构体类型变量*/,7.1 结构体,定义结构体类型的同时定义结构体类型变量 例如:在定义结构体类型时定义变量。 struct date int year; int month; int day; mydate1,mydate2;,7.1 结构体,直接定义结构体类型变量 例如:结构体类型定义时不指定类型名,而直接定义变量。 struct char no8 /* 编号 */ char name10; /* 姓名 */ char sex; /* 性别 */ float b_salary,f_salary,p_salary; /*基本工资、活工资、奖金*/ person1,person2; /* 定义该结构体类型变量 */,7.1 结构体,结构体变量一旦进入其作用域,系统便根据结构体类型定义时成员排列的先后,自动为结构体变量的每一个成员分配相应的存储空间。结构体变量的各个成员均有自己的存储空间,结构体变量所占存储空间的大小为各成员所占空间之和。 例如:student1 所占空间大小为:8 + 10 + 1+ 4 * 2 = 27(字节)。 mydate1所点空间大小为:2 + 2 + 2 = 6(字节)。 person1所占空间大小为:8 + 10 + 1 + 3 * 4 = 31(字节)。,另外,还可以直接使用sizeof()关键字来计算结构体变量的大小。 例如: printf(%d, %d n, sizeof(student1), sizeof(person1); 该语句的输出结果为:27 ,31,7.1 结构体,C语言中,对结构体变量的输入、输出、赋值和运算等操作一般都是通过结构体变量的成员引用来实现的。结构体变量的成员引用,可使用成员运算符“.”来引用。引用的形式为: . 若定义的结构体类型及变量如下: struct date int day; int month; int year; today; 则变量today各成员的引用形式为: today.day、today.month、today.year。,7.1 结构体,结构体变量的初始化与一维基本类型数组的初始化方法相似。不同的是,对一维数组来说,是初始化数组元素(各元素类型相同),对结构体变量,则是初始化结构体成员(各成员类型可能不同)。,由于结构体类型变量可以汇集各类不同数据类型的成员,所以结构体类型变量的初始化必须在结构体类型变量定义时进行 。 例如:stu_info结构体类型定义如前所述,该类型变量的初始化形式为: struct stu_info student = “06050113“,“li ping“,f,20,“computer science“;,7.1 结构体,也可以使用标准的输入、输出函数完成对结构体类型变量成员的输入(赋值)、输出。由于结构体类型变量成员的数据类型通常是不一样的,用scanf同时输入不同类型的成员数据常常会出现意想不到的情况,解决的方法有以下两种:,7.1 结构体,利用转换函数 将结构体类型变量成员以字符串的形式输入,利用C的类型转换函数将其转换为所需类型。类型转换的函数是: atoi(char*str);将数字字符串转换为整型。 atof(char*str);将数字字符串转换为双精度的实型。 atol(char*str);将数字字串转换长整型。 使用上述函数,要包含头文件“stdlib.h“。,7.1 结构体,例71类型转换函数在结构体变量数据输入中的应用示例。定义结构体类型及变量,输入一个学生的有关信息并输出。 例71源程序,7.1 结构体,利用简单变量 将结构体变量的成员的初始值用scanf()函数输入到简单变量中,再将其值赋给结构体成员变量。 例72借助简单变量实现结构体变量的数据输入。 例72源程序,7.2 结构体数组的定义和引用,结构体数组的定义方法和基本型数组的定义方法相似,只需在定义数组时指明其数据类型为相应的结构体类型。结构体类型数组的定义形式为: struct 结构体名 数组名元素个数; 例如:定义学生成绩结构体类型数组。 struct stu_scr /*定义学生成绩结构体类型*/ char name10; /*学生姓名*/ char sex; /*性别*/ float score3; /*三科考试成绩*/ ; struct stu_scr student20; /*定义具有20个元素的结构体数组student */,7.2 结构体数组的定义和引用,由于结构体数组中的每一个元素相当于一个结构体变量,因此引用其数组元素的成员的一般形式为: 结构体数组名下标.成员名 对于上述结构体数组student, 其数组元素各成员的引用形式为: 、student0.sex、student0.scorei; 、student1.sex、student1.scorei; . 、student19.sex、student19.scorei;,7.2 结构体数组的定义和引用,可以对结构体数组进行初始化,初始化方法与二维基本型数组的初始化方式相似。初始化的格式为: Struct 结构体名 数组n元素初值1,元素初值2,.,元素初值n; 例如:对二维基本型数组以及结构体数组的初始化。 int a24 = 1,2,3,4, 5,6,7,8; struct stu_scr myclass2 = zhang san, f, 89, 90, 99, li si, m, 89, 95, 78;,7.2 结构体数组的定义和引用,结构体数组的输入与输出一般在循环结构中进行,一次循环可以输入或输出一条结构体记录。 例73定义一个结构体数组用于存储和显示三个学生的基本信息。 例73源程序 程序运行结果如下:,no. name sex age depart 06030217 zhang san m 19 Economy & Commerce 06050105 li si m 18 engineering 06010116 wang wu f 18 Computer science,7.3 指向结构体的指针,指向结构体变量的指针变量的定义与指向基本类型的指针变量的定义一样。其一般定义形式为: Struct 结构体类型名 *指针变量名 例如:定义指向结构体变量的指针变量。 struct stu_info *q; /* q为指针变量,指向结构体类型stu_info*/ 例如:在定义结构体类型时定义结构体指针变量。,7.3 指向结构体的指针,struct stu_cj char no8; /* 学号*/ char name10; /* 姓名*/ float score4; /* 3门课成绩及平均成绩*/ stud, *p1, *p2; /* p1、p2为指针变量,指向结构体类型stu_cj*/ 系统为结构体变量分配存储空间后,结构体变量及成员都有自己的地址。 例如:变量的地址:&stud 成员的地址:&stud.no、&、&stud.score0,7.3 指向结构体的指针,将一个结构体变量的起始地址赋给一个指针变量后,则指针变量就指向该结构体变量,可以通过该指针变量来引用结构体变量的成员,引用形式为: 指针变量-成员; (*指针变量).成员; 例如:指针变量p1,p2指向结构体变量x。 p1 = p2 = 例如:通过结构体指针p1和p2来引用结构体变量x成员。以下三种方式是等价的。 x.no、、x.score0 p1-no、p1-name、p1-score0 (*p2).no、(*p2).name、(*p2).score0,7.3 指向结构体的指针,将结构体数组的起始地址赋予指针变量,则指针变量指向结构体数组,可以通过该指针变量访问数组元素。 例74使用指向结构体数组的指针来访问结构体数组 例7.4源程序,7.4 结构体与函数,结构体传递给函数的方式 向函数传递结构体变量的成员 向函数传递结构体变量 传递结构体变量的地址,7.4 结构体与函数,结构体作为函数形参,函数的定义形式: 传值方式:返回类型 函数名(struct 结构体名 形参名,) 传引用方式: 返回类型 函数名(struct 结构体名 *形参名,) 结构体作为函数实参,函数的调用形式: 传值方式: 函数名(结构体变量名,) 传引用方式:函数名(结构体变量名,),7.4 结构体与函数,例 75 用函数实现结构体类型数据的输入和输出。 例 7.5源程序 例 7.6 根据表7-2所示学生成绩表,定义相应的结构体类型,编程求解每门课的平均成绩及每个学生的平均成绩。,7.4 结构体与函数,表 72 学生成绩表,例 7.6源程序,7.5 复杂的结构体,结构体成员可以是基本类型,也可以是其他构造类型的成员。结构体中还可以包含其他结构体。 例如:结构体类型std_info中包含另一结构体类型date。 struct date /*日期结构类型:由年、月、日三项组成*/ int year; int month; int day; ;,7.5 复杂的结构体,struct std_info /*学生信息结构类型:包括学号、姓名、性别和生日*/ char no8; char name10; char sex; struct date birthday; ;,7.5 复杂的结构体,例如:结构体类型std_record中包含结构体类型std_info和score。 struct score /*成绩结构类型:由学号和三门成绩共4项组成*/ char no8; int score1; int score2; int score3; ; student std_record struct std_info stdxx; struct score cj; ;,7.5 复杂的结构体,如果某成员本身又是一个结构类型,则只能通过逐级使用成员运算符引用结构体成员。对最低一级的成员进行引用格式为: 结构变量.成员.子成员.最低级子成员,7.5 复杂的结构体,例77多级结构体成员的引用。 例77源程序,7.5 复杂的结构体,在结构体定义时,其成员定义为自身的结构体类型,这种方式称为结构体的自我引用。 例如:结构体中包含指向自身的结构体指针。 struct link char m; struct link *next; /* 定义指向自身的结构体指针 */ ; struct link x,y,z; /* 结构体变量的定义 */,7.6 链表,链表结构 单链表结构如图所示。 链表的基本操作有:创建、检索(查找)、插入、删除和修改等。,7.6 链表,在C语言中,用结构体类型来描述链表结点结构。例如: struct link int data ; /*数据域*/ struct link *next; /*指针域*/ ; 结构体类型中具有一个指向自身结构体类型的指针域的链表称为单链表或线性链表,有两个指针域的链表称为双向链表或二叉链表等,有三个及以上指针域的链表称多重链表。,7.6 链表,链表是一种动态存贮结构。在C语言中,使用系统提供的动态内存管理函数,为链表中的结点分配存储空间,或释放链表中的结点占用的存储空间,以实现数据的动态存储。内存分配函数主要有malloc()和calloc(),内存释放函数是free()。这两类函数的原型在stdlib.h中,要使用这些函数时,首先要用文件包含: include “stdlib.h” 或include ,7.6 链表,内存分配函数malloc() 函数原型: void * malloc(int size); 功能:分配大小为size的内存空间,返回分配内存空间的起始地址(void *类型)。若未能实现内存分配,则返回空指针(NULL)。 例如:int * p,* q; p = (int *) malloc (sizeof(int); /*分配2B,即整型数据长度*/ q = (int *) malloc (sizeof(int) * 100 ); /*分配200B*/,7.6 链表,内存块分配函数calloc() 函数原型: void * calloc(unsigned n ,unsigned size); 功能:分配n块大小为size的内存空间,返回该内存区域的起始地址。若未能实现分配,则返回空指针(NULL)。 例如:int * p; p = (int *) calloc (10,2); /* 分配10块大小为2B内存空间*/,7.6 链表,内存释放函数 free() 函数原型: void free(void * block); 功能:释放block指向的内存区域。block应当为内存分配函数的返回值。 例如: int * p; p = (int *) malloc(4); /*分配空间*/ *p = 100; free(p); /*释放 p 所指的内存空间*/ p = (int *) malloc ( sizeof(int) * 100 ); free(p);,7.6 链表,动态链表是指在程序执行过程中动态分配链表的结点空间而建立的长度可变的链表。创建动态链表有两种方式,一种是首部插入结点方式,一种是尾部插入结点方式。 首部插入结点方式:新生成的结点插入在表头,最后插入的结点即为表头结点。 尾部插入结点方式:新生成的结点插入到链表的最后。,7.6 链表,例78编写一个create()函数,创建一个动态单链表,即链表中的结点个数不限。 算法思路: 创建一个空链表; 生成一个新结点:向系统申请分配一个结点的空间,然后输入结点数据域的数据项,并将指针域置为空(链尾标志); 将新结点插入到链表尾部。对于链表的第一个结点,应设置头指针变量。 例78源程序,7.6 链表,链表的插入操作是在结点ai-1与ai之间插入一个新的结点ax,使线性表的长度增1。,单个结点的后插操作, 建立新结点 s=(struct node *)malloc(sizeof(struct node),改变新结点前一结点的指针 p-next = s;, 向新结点中添入内容, 将新结点链入链中 s-next = p-next;,7.6 链表,例79编写一个insert()函数,实现在单链表的第k个结点后插入1个新结点的操作。当k = 0时,将新结点插入到第一个结点之前,成为链表新的首结点。当k大于链表长度,则将新结点插入到链表最后。 例79源程序,7.6 链表,删除操作是将链表的第i个结点删去。因为在单链表中结点ai的存储地址是在其直接前趋结点ai-1的指针域next中,所以应首先找到ai-1的存储位置p。然后令pnext指向ai的直接后继结点,即把ai从链上摘下。最后释放结点ai的空间。,链表的删除操作的实现步骤: 1.找直接前驱结点; 2.从链表中删除结点; 3.释放空间。,删除后继结点,7.6 链表,例710编写一函数,实现链表的删除操作。 例710源程序,7.6 链表,链表的查找操作是根据检索条件,顺序查找某个结点是否存在于链表中,若存在,则返回结点的存储位置,否则返回空。链表的查找分按序号查找和按值查找两种方式。,7.6 链表,按序号查找 由于链表是一个顺序访问结构,因些,即使知道被访问结点的序号i,也不能直接按序号i访问结点,而只能从链表的头指针出发,按指针域next逐个结点往下搜索,直到搜索到第i个结点为止。 例711编写一函数,实现链表的按序号查找。 例711源程序,7.6 链表,按值查找 按值查找是在链表中查找是否有结点值等于给定值key的结点,如果有的话,则返回首次找到的其值为key的结点的存储位置;否则返回NULL。查找过程从头指针出发,顺着链表逐个将结点的值和给定值key作比较。 例712编写一函数,实现链表的按值查找。 例712源程序,7.6 链表,链表的输出操作 从链表的头指针开始依次输出各结点的数据域。 例713编写一函数,实现链表的输出。 例713源程序,7.6 链表,例714链表操作综合示例。利用create()建立一个链表,并实现链表的插入、删除、查找和输出等操作。 例714源程序,7.7 共用体,共用体类型的定义与结构类型的定义类似。 union 共用体类型名 数据类型 成员1; 数据类型 成员2; 数据类型 成员n; ; 例如: union data int ii; char cc; float ff; ;,7.7 共用体,共用体变量的定义与结构体变量的定义类似,也有三种定义方式。 先定义类型、再定义变量 例如:定义共用体类型data变量。 union data un1, un2, un3; /* un1、un2和un3为共体体类型变量。*/,7.7 共用体,定义类型时定义变量 在定义共用体类型时,将变量定义写在“”与“;”之间。例如: union data int ii; char cc; float ff; u4,u5; /* un4和un5为共用体类型变量。*/,7.7 共用体,直接定义共用体类型的变量 例如 :缺省共用体类型名,直接定义变量 union int i; char ch; float f; un7, un8;,7.7 共用体,共用体与结构体都是由成员构成,但二者有本质的不同。结构体中各成员有自身的独立的存储空间,结构体变量的长度为各成员长度之和,而共用体变量所占用的内存空间等于最长成员的长度,而不是各成员长度之和,各成员在共同体变量存储空间内享有自身类型大小的存储空间,成员间的存储空间有重叠。,7.7 共用体,例如:结构体变量与共用体变量存储的区别。 结构体: 共用体: struct st_data union un_data; int ii; int ii; char ch; char ch; float ff; float ff; st_var; un_var;,7.7 共用体,7.7 共用体,共用体变量成员引用 共用体变量与结构体变量一样,也只能逐个引用共用变量的成员。共用体变量成员引用三种形式: 共用体变量名.成员名 指针变量名-成员名 (*指针变量名).成员名 例如:访问共用变量un1各成员: un1.i、un1.ch、un1.f。,7.7 共用体,例如: union un_data1 int i; float f; char str5; undata, *unp; unp = undata.str、undata.str1。 unp-str、unp-str1。 (unp).str、(unp).str1,7.7 共用体,共用体变量定义时也可以初始化,但初始化值只能给第一个成员。 例715共用体变量的初始化 例715源程序 程序运行结果是: x: 65 A 0.000000 y: 70 F 0.000000 y = x 65 A 0.000000,7.7 共用体,例716将一个16位(2B)整型数据按高8位(1B)和低8位(1B)输出。 例716源程序 程序运行结果为: ax = 1234 ah = 12 al = 34,7.8 位域,位域的定义方式与一般结构体成员相似。在结构体类型定义时,只需定义相应的以位为单位的成员即可。位域定义的一般形式为: struct 结构体类型名 类型说明符 位域名1:位域长度1; 类型说明符 位域名2:位域长度2; 类型说明符 位域名n:领域长度n; ;,7.8 位域,例如:定义包含位域的结构体类型及变量。 struct st_bs1 unsigned a:7; unsigned b:2; char c; unsigned d:4 ; struct st_bs1 b_data; /*定义变量*/,7.8 位域,位域的引用方法与结构体成员的引用方法相同,使用成员运算符“.”来引用结构体变量的位域。引用的一般形式为: 结构体变量名.位域名 例7.17位域的引用示例。 例7.17源程序 程序运行结果为: 1,7,15 1,7,15,7.9 枚举类型,枚举类型的定义形式: enum 枚举类型名 枚举取值列表; 例如:enum weekdays sun, mon, tue, wed, thu, fri, sat; 说明:枚举取值列表中应列出该类型的变量所用可能的取值,这些值也称为枚举元素,是C语言用以描述客观事物的合法标识符。,7.9 枚举类型,枚举变量的定义与结构体变量和共用体变量定义类似。 间接定义方式:先定义类型,再定义变量。例如: enum weekdays sun, mon, tue, wed, thu, fri, sat; /*先定义类型*/ enum weekdays workday; /*再定义变量*/ 直接定义方式:在定义类型时定义变量。例如: enum weekdays sun, mon, tue, wed, thu, fri, sat workday; /*定义类型时定义变量*/,7.9 枚举类型,例718

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论