[工学]第8章 结构体类型和联合体类型_第1页
[工学]第8章 结构体类型和联合体类型_第2页
[工学]第8章 结构体类型和联合体类型_第3页
[工学]第8章 结构体类型和联合体类型_第4页
[工学]第8章 结构体类型和联合体类型_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

程序设计技术,1 C语言数据描述和C程序设计初步 2 结构化程序设计基础和C语言的控制结构 3 数组及其应用 4 函数与C程序结构 5 指针与函数 6 指针与数组 7 字符串及其应用 8 结构体类型和联合体类型 9 C语言的文件处理及其应用 10 位运算与枚举类型,结构体类型和联合体类型,8.1 结构体数据类型的基本概念 8.2 结构体数组 8.3 结构体数据类型与指针的关系8.4 结构体数据类型的简单应用单链表 8.5 联合体数据类型的基本概念,结构体数据类型的基本概念,结构体数据类型的基本概念问题的提出 在实际的计算机应用问题中特别是在事务处理中,常常需要将不同的数据组合成为一个有机的整体,形成一种能够既表示出各个数据又表示出这些数据之间关系的构造数据类型。解决办法 在C程序设计语言中提供了构造这种数据类型的能力,称这种由一些属于不同数据类型的数据组合而成的构造数据类型为结构体类型。,结构体类型的特点:结构体类型由若干个数据项组成,其中的每一个数据项称为一个结构体成员,它们都属于一种已经有定义数据类型;系统并没有预先定义结构体类型,凡要使用结构体类型数据则需要在程序中进行定义。可以根据不同的需要在程序中定义若干个结构体类型;一个特定的自定义结构体类型只在其定义存在的源程序中起作用,在其他源程序中则不能使用;要使用结构体类型数据,必须要先定义结构体类型,然后再定义此种类型的变量;,结构体数据类型的基本概念,结构体类型的定义struct 标识符 数据类型名 结构体成员1; 数据类型名 结构体成员2; 数据类型名 结构体成员n;;式中:struct 标识符一起构成结构体数据类型的类型名; 数据类型名 结构体成员i;确定了结构体类型中的一个结构体成员,其定义形式如前面的变量定义;一个结构体类型定义完成后这种数据类型就存在于C源程序中,在同一个源程序中可以定义该种数据类型的变量。,struct student long id; char name20; int age; char sex; char address80; long tel;,结构体数据类型的基本概念,结构体类型的定义定义结构体类型变量的方法 先定义类型,然后定义变量。其形式为: struct 标识符 变量列表定义结构体类型时同时定义结构体变量。其形式为: struct 标识符 结构体成员列表; 结构体变量列表;直接定义结构体变量。其一般形式为: struct 结构体成员列表; 结构体变量列表;,结构体数据类型的基本概念,结构体类型的定义定义结构体类型变量举例先定义类型,然后定义变量 同时定义结构体类型和变量 只定义结构体类型变量,结构体数据类型的基本概念,结构体类型的定义结构体类型的嵌套定义结构体类型可以嵌套定义,即定义的一个结构体类型的成员中可以有属于另外一个已经定义完成的结构体类型的变量。,struct date int year; int month; int day;,struct student long number; char name20; struct date birthday; int age; char address80; long tel;,结构体数据类型的基本概念,关键字typedef的简单应用typedef关键字的主要作用为已经存在的数据类型取一个新的名字(别名); 根据需要构造复杂的数据类型;使用typedef 为已经存在的数据类型取别名使用typedef可以为已经存在的数据类型取别名,定义别名后程序中既可以使用原类型名,也可以使用其别名。定义别名的一般形式为:typedef 数据类型名 别名;,typedef int INTEGER;(为系统整型int类型取别名INTEGER)int j,k; 等价于 INTEGER j,k;,typedef struct student long number; struct date birthday; char name20; int age; char sex; char address80; long tel;STU;struct student 等价于 STU,struct student long number; struct date birthday; char name20; int age; char sex; char address80; long tel;;typedef struct student STU;struct student 等价于 STU,结构体数据类型的基本概念,关键字typedef的简单应用使用typedef构造复杂数据类型 在不同的应用环境中对复杂结构数据的要求是不同的,所以使用typedef关键字构造复杂结构数据没有统一的形式,在应用程序中应该根据需要构造合适形式的数据类型。构造指定长度的字符串数据类型 typedef char String100; String是字符串数据类型的类型名,其每个变量都可以容纳最多99个有效字符。 String s1; 等价于 char s1100;例8-1 用typedef构造指定长度的字符串数据类型。,例8-1 用typedef构造指定长度的字符串数据类型。,#include #include typedef char String100;/*构造了长度为100的字符串数据类型String */void main()String s1,s2;printf(Input string s1 ,结构体数据类型的基本概念,关键字typedef的简单应用使用typedef构造复杂数据类型构造指定行列的二维数组类型#define N 5#define M 10typedef int arrN;typedef arr ArrayM;Array是M行N列整型二维数组类型的类型名,其每个变量都是一个M行N列的整型二维数组。Array a1; 等价于 int a1MN;例8-2 用typedef构造指定行数和列数的二维数组类型 。,结构体数据类型的基本概念,关键字typedef的简单应用使用typedef构造复杂数据类型构造指针数据类型typedef int *IP;IP是整型指针类型的类型名,其每个变量都是指向整型数据的指针变量。IP ptr; 等价于 int *ptr;例8-3 用typedef构造指针数据类型。,结构体数据类型的基本概念,关键字typedef的简单应用使用typedef构造复杂数据类型构造指向函数的指针数据类型typedef double (*FP)(double); FP是指向函数指针类型的类型名,其每个变量都是一个指向拥有一个double类型形参、返回值类型为double的函数的指针变量。 FP ptr; 等价于 double (*ptr)(double x);例8-4 用typedef构造指向函数的指针数据类型。,结构体数据类型的基本概念,8.1.3 结构体变量的引用和输入输出结构体变量的初始化 结构体变量初始化的形式类似于一维数组,其不同之处在于结构体变量的成员值根据其所属类型可以是不同类型的数据。初始化的一般形式为: struct 标识符 变量名=结构体变量成员值列表; 例:struct student stu1=5001, ”Liwei”, 1988,12,30,19,”12 songlin”,65102621;,结构体数据类型的基本概念,结构体类型的定义和结构体变量的使用方法结构体类型变量的引用结构体变量一般也不能进行整体操作。只能通过对其中的每一个数据项的操作达到操作结构体变量的目的。对于结构体变量中每一个数据项(成员分量)的引用要使用点运算符以组合成结构体成员分量,其一般形式为: 结构体变量名.成员分量名 嵌套结构体类型变量的引用对于嵌套的结构体类型的变量,访问其成员时应采用逐级访问的方法,直到得到所需访问的成员为止。其形式为: 结构体变量名.一级成员分量名.二级成员分量名,结构体数据类型的基本概念,结构体类型的定义和结构体变量的使用方法结构体类型变量的输入输出不允许把结构体变量作为整体进行输入或输出的操作,只能将结构体变量的成员作为输入输出的对象。同类型结构体变量的赋值当有两个同类型的结构体变量时,可以将一个结构体变量作为一个整体赋值给另外一个结构体变量。 例:struct student stu1=10001,”Liwei”,1980, 12,30,19,”12 songlin”,65102621; struct student stu2=stu1;,例8-5 结构体变量引用和输入输出示例。,结构体数据类型的基本概念,8.1.4结构体变量作为函数参数结构体类型变量可以作为函数的参数在函数之间进行传递。使用结构体类型变量作为函数参数时,数据的传递仍然是“值传递方式”;实现方式:函数调用时系统为形参变量开辟一段内存单元(按照结构体变量所需要的存储单元数)以存放从实参传递过去的各结构体变量成员分量的值。例8-6 结构体变量作为函数参数使用示例。,结构体数据类型的基本概念,8.1.5 结构体作函数的返回值类型返回结构体类型函数概念结构体类型数据对象不但能够作为函数参数在函数之间传递,也可以作为函数的返回值。当函数的返回值类型是一个结构体类型时,该函数就称为返回结构体类型的函数。函数定义的形式 struct 标识符 函数名(形式参数表及定义) 函数的定义和声明部分; 函数的执行部分;,例8-7 返回结构体类型函数的使用示例。,结构体类型和联合体类型,8.1 结构体数据类型的基本概念 8.2 结构体数组 8.3 结构体数据类型与指针的关系8.4 结构体数据类型的简单应用单链表 8.5 联合体数据类型的基本概念,结构体数组,结构体数组的定义和数组元素的引用结构体数组概念 一个结构体变量可以存放一组数据以描述一个对象的相关信息,如果存在若干个同类型的对象则需要使用多个具有相同结构的结构体变量。可以将这些相同类型的结构体变量组成结构体数组。结构体数组中的每一个数组元素都是结构体变量,结构体数组特别适用于处理具有若干相同关系的数据组成的集合体。 结构体数组的定义 定义结构体数组的方式与定义结构体变量相同,也有三种方法。如果以定义好结构体类型,则结构体数组定义的一般形式是: struct 标识符 数组名常量表达式;,结构体数组,结构体数组的定义和数组元素的引用结构体数组的存储形式构体数组各元素在系统内存中连续存放,每一数组元素的成员分量也按类型定义中出现的顺序依次存放。 结构体数组的初始化 由于结构体数组元素(结构体变量)一般总是由若干不同类型的数据组成的,而且结构体数组又由若干个结构体变量组成,所以结构体数组的初始化形式总与较它高一维的普通变量数组的初始化形式类似。初始化的一般形式是: struct 标识符 数组名=初始化数据列表;,例:设有结构体类型定义sturct person char name20; int count;struct person stu3=“Zhang”,0,”Wang”,0,”Li”,0;struct person stu3=“Zhang”,0,“Wang”,0,“Li”,0;,结构体数组,结构体数组的定义和数组元素的引用结构体数组元素的引用结构体数组元素就相当于一个结构体变量,所以引用数组元素成员分量的方法与前面介绍的引用结构体变量成员分量的方法相同,其一般形式为: 数组名下标.成员名 对结构体数组元素操作的惟一例外是可以将结构体数组元素作为一个整体赋给同一结构体数组的另外一个元素,或赋给一个同类型的结构体变量。例8-8 结构体数组操作(数组元素引用、数组元素的输入输出)示例。,结构体数组,结构体数组作函数参数结构体类型数组可以作为函数的参数在函数间进行传递。使用结构体类型数组作为函数参数时,实现的是“传地址值调用方式”。 同样实现的是实参数组将自己的全部或部分区域提供给形参数组共享的过程。,例8-9 结构体数组作函数参数示例。,结构体类型和联合体类型,8.1 结构体数据类型的基本概念 8.2 结构体数组 8.3 结构体数据类型与指针的关系8.4 结构体数据类型的简单应用单链表 8.5 联合体数据类型的基本概念,结构体数据类型与指针的关系,8.3.1 结构体类型变量与指针的关系 概念结构体类型变量的指针就是该结构体类型变量所占内存区域的起始地址,同样也可以定义一个指针类型的变量来存放这个地址,即指向这个结构体类型变量。结构体指针定义形式struct 标识符 *指针变量名; 结构体指针变量的赋值 使用取地址运算符,struct person char name20; int count;stu, *p=,同样:对指针变量p取指针运算就是结构体变量stu,结构体数据类型与指针的关系,8.3.1 结构体类型变量与指针的关系 通过指针变量访问结构体类型变量的成员分量(*指针变量).成员名; 指针变量名-成员名;,结构体变量操作方式,通过指向结构体变量的指针变量操作结构体变量的方式,结构体数据类型与指针的关系,8.3.2 结构体类型变量与指针的关系 结构体类型指针作为函数参数使用结构体类型变量作为函数的参数时可以将整个结构体类型变量作为参数在函数之间进行传递。 特点:“传值调用”,将全部成员值一个一个传递,费时间,费空间,系统开销较大。 使用指向结构体类型变量的指针作为函数的参数。 特点:“传地址值调用”,不用传递大量的数据信息,从而可以大大提高应用程序的执行效率。 例8-10 输入若干个学生信息并输出,输入输出功能由函数实现。,结构体数据类型与指针的关系,8.3.2 结构体类型数组与指针的关系 将一个结构体类型数组的起始地址赋给同类型的指针变量,即让该指针变量指向结构体类型数组。 通过指针引用结构体数组元素时需要结合考虑数组元素是结构体变量的引用方法。,struct A char c; int x; ; struct A a5,*p1; p1=,例8-11 用指向结构体数组元素的指针操作结构体数组元素示例。,结构体数据类型与指针的关系,结构体类型数组与指针的关系,struct A char c; int x; ; struct A a5,*p2; p2=a;,例8-12 输入若干个学生信息并输出。,结构体类型和联合体类型,8.1 结构体数据类型的基本概念 8.2 结构体数组 8.3 结构体数据类型与指针的关系8.4 结构体数据类型的简单应用单链表 8.5 联合体数据类型的基本概念,结构体数据类型的简单应用单链表,自引用结构和结点的定义 C语言中的自引用结构在定义结构体构造数据类型的时候,结构体类型中的数据成员可以是该结构体类型自己的指针类对象(包括指针变量和指针数组)。这种在一个结构体类型定义中包含有该结构体类型指针类对象的结构体称为自引用结构。,/正确的自引用结构struct test char ch; struct test *next; ;,/错误的自引用结构struct test char ch; struct test next; ;,结构体数据类型的简单应用单链表,自引用结构和结点的定义 互相引用的自引用结构在应用程序的设计中需要两个结构体对象相互引用,也可以使用一种自引用结构的变形,即在两个结构体类型的定义中分别包含指向对方的指针。,struct A int x; struct B *pb;struct B int y; struct A *pa;,例8-13 互相引用的自引用结构示例。,结构体数据类型的简单应用单链表,自引用结构和结点的定义数据的逻辑结构数据组织形式从逻辑上抽象地反映了数据元素之间的结构关系,则称这种数据之间的结构关系为数据的逻辑结构。数据的逻辑结构包含两个大类:线性结构和非线性结构,线性表是常见的一种数据逻辑结构。 数据的物理结构用计算机对数据进行处理必须将数据存储到计算机中去,数据的逻辑结构在计算机存储设备中的映像(具体存储形式)称为数据的存储结构,亦称为数据的物理结构,在对线性表的处理中,其主要的存储结构有顺序存储结构和链式存储结构两种。,结构体数据类型的简单应用单链表,自引用结构和结点的定义链表使用的数据元素结点的定义 线性链表使用一组任意的、可以不连续的存储单元存储线性表的数据元素,此时称线性表中的数据元素为结点。在线性链表中,除第一个结点之外,其余每一个结点的存放位置由该结点的前一个结点在其指针域中指出。为了能够确定线性链表中的第一个结点的存放位置,使用一个指针指向链表的表头,这个指针称作“头指针”。线性链表的最后一个结点没有后继,该结点的指针域赋值为空(NULL或)。 链表与顺序表相比优点:可以根据处理数据的增减动态增长;在进行数据元素的插入和删除操作的时候不需要移动数据元素。 短处:链表是一种顺序访问结构;链表需要指针域用于结点之间的连接,因而链表的存储密度没有顺序表高。,结点,在记录学生的成绩的示例中,采用动态分配的办法为一个结构分配内存空间。每一次分配一块空间可用来存放一个学生的数据,我们可称之为一个结点。,有多少个学生就应该申请分配多少块内存空间,也就是说要建立多少个结点。,结构数组,当然用结构数组也可以完成上述工作,但如果预先不能准确把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占用的空间从数组中释放出来。另一方面,用数组的方法必须占用一块连续的内存区域。而使用动态分配时,每个结点之间可以是不连续的(结点内是连续的)。,链表(动态存储),用动态存储的方法可以很好地解决这些问题。有一个学生就分配一个结点。无须预先确定学生的准确人数,某学生退学,可删去该结点,并释放该结点占用的存储空间。从而节约了宝贵的内存资源。,单链表,单链表是最简单的一种线性链表。单链表的结点中,除了包含表示数据元素信息的数据域外,还包含一个用于链接的指针域。,typedef struct node elementtype data; struct node *next;NODE;,某种已定义好的表示结点数据域的数据类型,用于链接的指针域,链表,结点之间的联系可以用指针实现。 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。,链表,可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。第0个结点称为头结点,它存放有第一个结点的首地址,它没有数据,只是一个指针变量。最后一个结点因无后续结点连接,其指针域可赋为NULL。这样一种连接方式,在数据结构中称为“链表”。,简单链表示意图,以下的每个结点都分为两个域,一个是数据域,存放各种实际的数据,如学号num,姓名name,性别sex和成绩score等。另一个域为指针域,存放下一结点的首地址。链表中的每一个结点都是同一种结构类型。,一个存放学生学号和成绩的结点应为以下结构 :struct stu int num; int score; struct stu *next;,结构体数据类型的简单应用单链表,链表的基本操作 单链表的构造单链表的构造方法有两种:正向生成构造法单链表的正向生成的步骤主要分为两步:首先创建单链表的头指针,然后将新结点依次链接到单链表的尾部。反向生成构造法单链表的反向生成的步骤主要分为两步:首先创建单链表的头指针,然后将新结点依次插入到单链表的头部。,结构体数据类型的简单应用单链表,反向生成法构造单链表算法: NODE *create(int n)/* 构造具有n个结点的单链表 */ NODE *p,*h; int i; char inbuf10; h=(NODE *)malloc(sizeof(NODE); /* 创建单链表的头结点 */ h-next=NULL; for(i=n;i0;i-) p=(NODE *)malloc(sizeof(NODE); /* 为新结点分配存储 */ gets(p-name); gets(inbuf);p-score=atof(inbuf);p-next=h-next; /* 将新建结点插入到单链表的头结点之后 */h-next=p; return h;,结构体数据类型的简单应用单链表,链表的基本操作 单链表的输出所谓单链表的输出实质上就是对某一头指针指向的单链表进行遍历,也就是将单链表中的每一个数据元素结点从表头开始依次处理一遍。,带头结点单链表输出算法:void printlist(NODE *h) NODE *current=h; while(current-next!=NULL) current=current-next; printf(%st%fn, current-name,current-score); ,结构体数据类型的简单应用单链表,链表的基本操作 单链表的插入运算 实现在单链表上插入一个结点。基本过程如下:创建一个新结点;按要求寻找插入点;被插入结点的指针域指向插入点结点的后继结点;插入点结点的指针域指向被插入的结点;,结构体数据类型的简单应用单链表,带头结点的单链表中实现的插入结点算法:void insertlist(NODE *h,char *s) NODE *p,*old,*last; char inbuf20; /* 创建新结点 */ p=(NODE *)malloc(sizeof(NODE); printf(tInput the data :n); gets(p-name); gets(inbuf); p-score=atof(inbuf); last=h-next; /* 按某种方法寻找新结点的插入位置 */,while(strcmp(last-name,s)!=0 ,h,h-next,last,old,last-next,last,结构体数据类型的简单应用单链表,链表的基本操作 单链表的删除运算 实现在单链表中删除一个数据元素结点。 基本过程如下:查找被删除结点以及其前趋结点;被删除结点的前趋结点指针域指向被删除结点的直接后继结点;释放被删除结点;,结构体数据类型的简单应用单链表,带头结点的单链表中实现的删除结点算法:void deletelist(NODE *h,char *s) NODE *q=h,*p=h-next; /* 定位被删除结点及其前趋*/ while(strcmp(p-name,s)!=0 ,结构体数据类型的简单应用单链表,链表的基本操作 例8-14 带头结点单链表基本操作示例。要求设计一个简单的菜单,根据对菜单项的选择分别实现带头结点单链表的构造操作、插入操作、删除操作和输出操作。解题思想:分别设计出对带头结点单链表操作算法如下:构造具有n个结点的单链表NODE *create(int n);在单链表中插入一个新的结点void insertlist(NODE *h, char *s); 在单链表中删除一个指定结点void deletelist(NODE *h, char *s);输出单链表void printlist(NODE *h);,结构体类型和联合体类型,8.1 结构体数据类型的基本概念 8.2 结构体数组 8.3 结构体数据类型与指针的关系8.4 结构体数据类型的简单应用单链表 8.5 联合体数据类型的基本概念,联合体数据类型的基本概念,问题的提出及对策问题的提出在计算机应用的实践中,常常遇到数据对象的某一个区域值会随条件不同而为不同内容的情况。此时要求在程序设计中通过实现同一存储区域数据(类型)的可变性来增强数据项处理的灵活性。 解决方法C程序设计语言通过支持定义联合体(共用体)类型数据来适应计算机程序设计中的上述要求。,联合体数据类型的基本概念,联合体类型的定义和变量的引用方法 联合体类型的定义联合体类型的定义确定了参与共用存储区域的成员项以及成员项具有的数据类型 。联合体类型定义的形式为:union 标识符 数据类型 成员项1; 数据类型 成员项2; 数据类型 成员项n;,联合体数据类型的基本概念,联合体类型的定义和变量的引用方法 联合体类型变量的定义先定义联合体类型,然后定义联合体变量 union 标识符 成员列表; union 标识符 变量列表; 定义联合体类型的同时定义联合体类型变量 union 标识符 成员列表;变量列表 不定义类型名直接定义联合体类型变量 union 成员列表;变量列表,union test int a; long b;key; 定义了一个联合体类型union test和一个该类型的联合体类型变量key,16位系统中该类型所占的存储单元长度为4个字节,由变量key的两个成员分量分时复用(共享)

温馨提示

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

评论

0/150

提交评论