C语言程序设计教程(第4版)-第9章-结构_第1页
C语言程序设计教程(第4版)-第9章-结构_第2页
C语言程序设计教程(第4版)-第9章-结构_第3页
C语言程序设计教程(第4版)-第9章-结构_第4页
C语言程序设计教程(第4版)-第9章-结构_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

C语言程序设计教程

(第4版)第9章结构李丽娟2013年2月第9章结构本章主要内容1.了解结构数据类型的定义及使用。2.了解结构数据类型的意义及作用。3.了解结构变量与函数的关系。4.掌握链表的作用及操作。5.了解联合数据类型的定义及使用。6.了解枚举类型的定义及使用。第9章结构结构体数据类型:一种自定义的数据类型。由不同数据类型的数据组合而成的数据整体。结构体中所包含的数据元素称之为成员。如:“职员”——→一种结构体描述职员的信息有:编号、姓名、年龄、性别、身份证号码、民族、文化程度、职务、住址、联系电话等。9.1

结构体数据类型9.1.1结构体的定义结构类型的定义形式:

struct结构体名 {

成员项表列; };成员项表列同简单变量的定义形式相同。例如:对“职员”数据,可以定义如下的结构体类型:structperson{longno;

/*职员号*/charname[12];

/*姓名*/intage;

/*年龄*/charsex;

/*性别*/longindentityNo;

/*身份证号*/chareducation[12];

/*学历*/charaddr[40];

/*住址*/longtelno;

/*电话号码*/};9.1

结构体数据类型9.1.2结构体变量的定义定义了结构体之后,就可以定义结构体变量。结构变量的定义形式。(1)类型标识符

<变量名列表>;例如:

struct

person

stu,worker;(2)在定义一个结构体类型的同时定义结构体类型变量:

struct<结构体名> {

成员项列表; }<变量名列表>;(3)直接定义结构体类型的变量:

struct

{

成员项列表;

}<变量名列表>;9.1

结构体数据类型9.1.3结构体变量的初始化

(略)9.1.4结构体变量成员的引用(1)引用结构体变量中的成员。

引用格式:<结构变量名>.<成员名>例如:

stu.no、

stu.age、

[0]等。成员名不能单独代表变量,不能直接使用结构中的成员名。若结构体类型中含有另一个结构类型,访问该成员时,应采取逐级访问的方法。(2)将结构体变量作为一个整体来使用。结构体变量可以相互赋值。

(条件是这两个变量必须具有相同的结构体类型。)9.1

结构体数据类型例1:阅读程序example9_1.c,了解结构体成员的使用方法。9.1.5结构体变量成员的输入/输出只允许对结构变量的成员进行输入输出。不允许将结构体变量作为整体进行输入或输出操作。9.2结构体数组9.2.1结构体数组的定义结构体数组的定义:(1)先定义结构体,再定义结构体数组。

struct<结构体名> { <成员项表列> };

struct<结构体名>

<数组名>[<数组大小>];(2)在定义结构体的同时,定义结构体数组。

struct<结构体名> { <成员项表列> }<数组名>[<数组大小>];9.2结构体数组(3)直接定义结构体变量而不定义结构体名。 struct { <成员项表列> }<数组名>[<数组大小>];9.2.2结构体数组成员的初始化和引用

(略)9.3结构体变量与函数9.3.1函数的形参与实参为结构体作用:传值例2:阅读程序example9_2.c,了解结构变量作为函数参数的作用。9.3.2函数的返回值类型为结构体新的C标准中允许函数的返回值为结构体类型的值。例3:修改例9-2所示的程序,将“输入购书信息”模块的返回值修改成结构类型。9.4联合体数据类型9.4联合体数据类型联合体又称为共用体。联合体类型与结构体类型的同异:相同之处:定义形式与结构体类型的定义形式相同。

不同之处:①关键字不同,共用体的关键字为union。

②占用的内存单元不同。特点:

不同类型的数组项在内存中所占用的起始单元是相同的。提示:

注意联合类型变量的使用特点。9.4联合体数据类型比较结构类型变量和联合类型变量占用的内存情况:结构类型:structmemb{floatv;intn;charc;}stag;联合类型:unionmemb{floatv;intn;charc;}utag;stag占用内存单元utag占用内存单元9.4联合体数据类型例4:阅读程序example9_4.c,分析和了解联合体变量成员的取值情况。例5:阅读程序example9_5.c,了解联合体类型变量的赋值情况。9.5枚举数据类型枚举数据类型:用标识符表示的整数常量的集合。枚举类型定义的一般形式:

enum<枚举类型名>{标识符1,标识符2,……,标识符n};枚举常量的起始值为0。例如:

enummonths{JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};标识符的值被依次自动设置为整数0~11。可以改变标识符的取值,例如:

enummonths{JAN=1,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};标识符的值被依次自动设置为整数1~12。9.5枚举数据类型几点说明:枚举类型定义中的标识符必须是唯一的。可以在枚举类型定义时为每一个枚举常量指定不同的值。也可以对中间的某个枚举常量指定不同的值。例如:

enumclolor{red,blue,green,yellow=5,black,white};由于只指定了yellow的值,则枚举常量的取值情况为: red=0,blue=1,green=2, yellow=5,black=6,while=7。枚举常量的值不可更改,但可以作为整型数使用。9.5枚举数据类型枚举变量的定义形式:

enum<枚举类型名>变量名1,变量名2,……变量名n;例如:

enummonthwork_day,rest_day;也可以在定义枚举类型的同时定义枚举变量。例如:

enumcolor{red,yellow,green}

light;枚举常量标识符是不能直接输入/输出的,要通过其他方式来输出枚举常量标识符。9.5枚举数据类型例6:阅读程序example9_6.c,了解枚举变量的输出方式。9.6链表的概念基本概念:①链表指的是将若干个数据项按一定的规则连接起来的表。②链表中的数据项称为结点。③链表中每一个结点的数据类型都有一个自引用结构④自引用结构就是结构成员中包含一个指针成员,该指针指向与自身同一个类型的结构。例如:

structnode {intdata;

structnode*nextPtr; };9.6链表的概念链表是用链节指针连接在一起的结点的线性集合。其结构如图所示:自引用结构成员的变量通常是指针型的。结构成员的引用与成员的类型相关。假如有:

structnode {

intdata;

structnode*nextPtr; };定义结构变量:

structnode*pt;结构成员的引用:

pt->data; pt->nextptr;或:

(*pt).data; (*pt).nextptr;9.6链表的概念链表可以组成较为复杂的数据结构。根据数据之间的相互关系,链表又可分为单链表、循环链表、双向链表等。链表的可以建立动态的数据结构,可以将不连续的内存数据连接起来。本章重点:单链表。其他链表参见“数据结构”等教程。9.6链表的概念9.6.1动态分配内存动态分配内存空间的系统函数:

malloc()和free()函数以及sizeof运算符的配合使用

(注:

malloc()和free()函数在头文件stdlib.h或alloc.h)。函数原型及功能如下。1.函数原型:void*malloc(unsignedsize)功能:从内存分配一个大小为size个字节的内存空间。若成功,返回新分配内存的首地址;若没有足够的内存分配,则返回NULL。通常函数malloc()通常和运算符sizeof一起使用。9.6链表的概念例如:

int*p;

p=malloc(20*sizeof(int));/*分配20个整型数所需的内存空间*/系统分配能存放20个整型数连续空间,

p指向该存储空间的首地址。例如: structstudent {intno;

intscore;

structstudent*next; }; structstudent*stu; stu=malloc(sizeof(structstudent));通过sizeof计算structstudent的字节数,分配sizeof(structstudent)个字节数的内存空间,

stu指向该存储空间的首地址。9.6链表的概念2.函数原型:voidfree(void*p)功能:释放由malloc函数所分配的内存块,无返回值。例如:free(stu);作用:将stu所指的内存空间释放。几点注意:①结构类型占用的内存空间不一定是连续的,因此,应该用sizeof运算符来确定结构类型占用内存空间的大小。②使用malloc()函数时,应对其返回值进行检测是否为NULL,以确保程序的正确。③要及时地使用free()函数释放不再需要的内存空间,避免系统资源过早地用光。④不要引用已经释放的内存空间。9.6链表的概念9.6.2单链表的建立链表:通过自引用结构的指针域,将各节点相互连接。关于链表的基本概念:(1)链表的第一个结点称头指针或头结点,它指向链表在内存中的首地址,(2)其后的结点是通过结点中的链节指针成员访问的。(3)链表的最后一个结点称为尾节点。尾节点的指针域通常被设置成NULL。(4)链表中的每一个结点是在需要的时候建立的。(5)各结点在内存中的存储地址不一定是连续的,由系统自动分配的,即有可能是连续分配内存空间,也有可能是跳跃式的不连续分配内存空间。9.6链表的概念建立单链表的主要步骤:①定义单链表的数据结构(定义自引用结构)。②建立表头(建立一个空表)。③利用malloc函数向系统申请分配一个结点空间。④将新结点的指针成员的值赋为空(NULL),若是空表,将新结点连接到表头;若非空表,则将新结点连接到表尾。⑤若有后续结点要接入链表,则转到③,否则结束。输出一个单链表的主要步骤:①找出表头结束,结点指针P指向头结点。②若P非空,循环执行下列操作。{

输出结点值;P指向下一结点;}9.6链表的概念例7:编写程序,创建一个链表,该链表可以存放从键盘输入的任意长度的字符串,以按下回车键作为输入的结束。统计输入的字符个数并将其字符串输出。程序:example9_7.c例8:编写程序,用链表的结构建立一条公交线路的站点信息,从键盘依次输入从起点到终点的各站站名,以单个“#”字符作为输入结束,统计站的数量并输出这些站点。分析:站点信息结构设计如下:

structstation { charname[8]; structstation*nextSta; };设计函数:structstation*creat_sta(structstation*h);

/*将键盘输入的站点名依次插入到链表h中*/程序:example9_8.c9.6链表的概念9.6.3从单链表中删除结点在链表中删去一个结点,不允许破坏原链表的结构。例如,对于这样的自引用结构:

structnode {intn;

structnode*next; };假定已建好链表:删除s节点后的链表:9.6链表的概念删除节点方法:修改指针域的值。根据被删节点的位置,修改指针域的方法要分3种不同情况:①s结点在表的中间(即不在表头,也不在表尾):

p->next=s->next;②s结点位于表头:

head=s->next;③s结点位于表尾:

p->next=NULL;结点删除后,用free()函数释放被删除结点所占用的内存空间。例如:free(s);

/*释放了节点s所占用的空间。*/9.6链表的概念例9:修改例9-8的程序,再从键盘输入一个要删除的站点名,并将删除后的站点依次输出。分析:在例9-8程序的基础上增加一个删除节点的函数:

structstation*del_sta(structstation*h,

char*str);函数功能:

在h所指的链表中,删除结点值为str所指字符串的结点。程序:

example9_9.c请分析函数:

structstation*del_sta(structstation*h,char*str);的算法。思考程序中存在的问题,怎样处理可以使程序更加完善?9.6链表的概念9.6.4向链表中插入结点插入节点方法:修改指针域的值。根据节点插入的位置,修改指针域的方法要分3种不同情况:①s结点插入到表中(即不在表头,也不在表尾)修改指针:

s->next=t; p->next=s;9.6链表的概念②s结点插入到表头。图(a)所示为插入前的链表,图(b)所示为插入后的链表。修改指针:

s->next=t; head=s;9.6链表的概念②s结点插入到表尾。图(a)所示为插入前的链表,图(b)所示为插入后的链表。修改指针:

p->next=s; s->next=NULL;9.6链表的概念例10:修改例9-8的程序,从键盘输入一个要加入的站点名,并将加入后的站点依次输出。分析:可以在例9-8程序的基础上增加一个增加节点的函数:structstation*add_sta(structstation*h,char*stradd,char*strafter);函数功能:将stradd所指的站点插入到h链表中站点原有的站点strafter的后面。程序:example9_10.c9.7程序范例例11:编写程序,从键盘输入一个矩形的左下角和右上角的坐标,输出该矩形的中心点坐标值,再输入任意一个点的坐标,判断该点是否在矩形内。分析:用xd、yd代表矩形的左下角坐标;用xu、yu代表矩形的右上角坐标;用xm、ym代表矩形的中点坐标;设计函数:intptin(structpointp,structrectr),用于判断输入的点p是否在矩形r的内部。程序:example9_11.c9.7程序范例例12:改进例8-25的程序。采用结构,设计一个洗牌和发牌的程序,用H代表红桃,D代表方片,C代表梅花,S代表黑桃,用1~13代表每一种花色的面值。分析:可用结构类型来表示扑克牌的花色和面值:

structcard{ char*face;/*扑克牌的面值*/ char*suit;

/*扑克牌的花色*/ };设计函数:voidshuffle(Card*)完成对扑克牌洗牌。程序:example9_12.c9.7程序范例例13:修改例9-12,用位段结构成员表示一副牌,发牌时显示每张牌的颜色。分析:因为牌的面值只有13种,牌的花色只有4种,牌的颜色只有2种,因此,可用一个位段结构来表示一副牌:struc

温馨提示

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

评论

0/150

提交评论