《C语言程序设计教程修订本 结构体与联合体.pptx》由会员分享,可在线阅读,更多相关《C语言程序设计教程修订本 结构体与联合体.pptx(45页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、8.1程序与程序文件程序与程序文件8.1.1结构体类型变量的定义结构体类型变量的定义定义结构类型变量包括两个方面:首先要定义结构体类型,以便确定该类型中有哪些成员,各成员属于什么数据类型;然后再定义属于该结构体类型的变量。第2页/共45页第1页/共45页1定义结构体类型定义结构体类型定义结构体类型的一般形式如下:struct结构体类型名成员表;其中在“成员表”中定义了该类型中有哪些成员,各成员属于什么数据类型。第3页/共45页第2页/共45页2定义结构体类型变量定义结构体类型变量定义结构体类型变量的一般形式为struct结构体类型名变量表;定义结构体类型与定义结构体类型变量是分开说明的。C语言
2、还允许在定义结构体类型的同时定义结构体类型变量。其形式为struct结构体类型名成员表变量表;第3页/共45页如果在函数体外定义了一个结构体类型,则从定义位置开始到整个程序文件结束之间的所有函数中均可定义该类型的变量;但在函数体内所定义的结构体类型,只能在该函数体内能定义该类型的变量。即结构体类型的定义与普通变量定义的作用域是相同的。第4页/共45页8.1.2结构体类型变量的引用结构体类型变量的引用在程序中定义了某结构体类型的变量后就可以被引用。结构体变量的一般引用方式如下:结构体变量名.成员名其中“.”为结构体成员运算符,它的优先级最高。第5页/共45页8.1.3结构体的嵌套结构体的嵌套C
3、C语言规定,结构体类型的定义可以嵌套。第6页/共45页8.1.4结构体类型变量的初始化结构体类型变量的初始化与普通变量一样,在定义结构体类型变量的同时也可以对结构体类型变量赋初值。但C语言规定,只能对全局的或静态的局部结构体类型变量进行初始化。为了将结构体类型变量定义为静态存储类型,在定义时应加上static关键字。但是,目前在大部分计算机系统中,对结构体类型变量初始化时不必加static关键字,其原理与普通数组的初始化一样。第7页/共45页8.1.5结构体与函数结构体与函数1结构体类型变量的成员作为函数参数结构体类型变量的成员作为函数参数与数组元素可以作为函数参数一样,结构体类型变量中的成员
4、也可以作为函数参数。在这种情况下,在被调用函数中的形参是一般变量,而调用函数中的实参是结构体类型变量中的一个成员,但要求它们的类型应一致。第8页/共45页2结构体类型变量作为函数参数结构体类型变量作为函数参数与一般变量可以作为函数参数一样,结构体类型的变量也可以作为函数参数。在这种情况下,在被调用函数中的形参是结构体类型的变量,调用函数中的实参也是结构体类型的变量,但要求它们属于同一个结构体类型。第9页/共45页3结构体类型的函数结构体类型的函数与定义标准数据类型函数一样,C语言也允许定义结构体类型的函数。结构体类型函数的返回值是结构体类型的数据。第10页/共45页8.2结构体数组结构体数组8
5、.2.1结构体数组的定义与引用结构体数组的定义与引用 与整型数组、实型数组、字符型数组一样,在程序中也可以定义结构体类型的数组。但C语言规定,同一个结构体数组中的元素应为同一种结构体类型。第11页/共45页例如,structstudentintnum;charname10;charsex;intage;floatscore3;stu10;定义了“学生情况”型的一个数组stu,可存放10个学生的情况。每一个学生的情况包括:学号(num)、姓名(name10)、性别(sex)、年龄(age)、3个成绩(score3)。实际上,定义了该数组后,相当于开辟了一个如表8.1所示的表格空间。第12页/共4
6、5页表8.1学生情况型的数组表格空间num学号name姓名sex性别age年龄score0成绩1score1成绩2score2成绩3第13页/共45页8.2.2结构体数组作为函数参数结构体数组作为函数参数与普通数组一样,结构体类型数组也能作为函数参数,并且形参与实参结合的方式完全一样。如果在被调用函数中改变了结构体类型形参数组元素中各成员值,实际上也就改变了结构体类型实参数组元素中的各成员值。因为结构体类型形参数组与结构体类型实参数组是同一个存储空间。第14页/共45页8.3结构体与指针结构体与指针8.3.1结构体类型指针变量的定义与引用结构体类型指针变量的定义与引用结构体类型的指针变量指向结
7、构体类型变量或数组(或数组元素)的起始地址。例如,structstudentintnum;charname10;charsex;intage;floatscore;structstudentst1,st2,st10,*p;其中定义了一个指向结构体“学生情况”型的指针p。第15页/共45页由上所述,当结构体类型的指针变量p指向一个结构体类型变量后,下列3种表示是等价的:结构体变量名.成员(*p).成员p成员它们都表示结构体变量中的一个成员。第16页/共45页8.3.2结构体类型指针作为函数参数结构体类型指针作为函数参数 结构体类型指针可以指向结构体类型的变量,因此,当形参是结构体类型指针变量时,
8、实参也可以是结构体类型指针(即地址)。在结构体类型指针作为函数参数的情况下,由于传送的是地址,因此,如果在被调用函数中改变了结构体类型形参指针所指向的地址中的值,实际上也就改变了结构体类型实参指针所指向的地址中的值。第17页/共45页例例8.7用结构体类型指针作为函数参数。在下面的程序中,主函数的功能是定义了一个结构体student型的变量st,同时为之初始化,然后输出变量st中各成员的值,将结构体类型变量st的地址(即&st)作为实参调用函数chang()后再输出变量st中各成员的值;函数chang()的功能是修改结构体类型形参指针t所指向的结构体类型数据中成员tscore的值,并输出修改前
9、后结构体类型指针所指向的数据中各成员的值。第18页/共45页#includestdio.hstructstudentintnum;charname10;charsex;intage;floatscore;voidchang(t)structstudent*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);第19页/共45页main()staticstructstudentst101,Zhang,M
10、,19,89.0;printf(st%6d%8s%3c%4d%7.2fn,st.num,st.name,st.sex,st.age,st.score);chang(&st);printf(st%6d%8s%3c%4d%7.2fn,st.num,st.name,st.sex,st.age,st.score);第20页/共45页 结构体类型指针也可以指向数组或数组元素,因此,当形参是结构体类型指针变量时,实参也可以是结构体类型数组名或数组元素的地址。与标准数据类型的数组与指针一样,在结构体类型数组指针作函数参数时,也可以有以下4种情况:(1)实参与形参都用结构体类型数组名;(2)实参用结构体类型数
11、组名,形参用结构体类型指针变量;(3)实参与形参都用结构体类型指针变量;(4)实参用结构体类型指针变量,形参用结构体类型数组名。第21页/共45页8.4链链表表8.4.1链表的基本概念链表的基本概念1链表的一般结构链表的一般结构链表由结点元素组成。为了适应链表的存储结构,计算机存储空间被划分为一个一个小块,每一小块占若干字节,通常称这些小块为存储结点。将存储空间中的每一个存储结点分为两部分:一部分用于存储数据元素的值,称为数据域;另一部分用于存放下一个数据元素的存储序号(即存储结点的地址),称为指针域。第22页/共45页每一个结点的结构如图8.1所示。图8.1链表的结点结构第23页/共45页在
12、链表中,用一个专门的指针HEAD指向链表中第一个数据元素的结点(即存放第一个数据元素的存储结点的序号)。链表中最后一个元素后面已没有结点元素,因此,链表中最后一个结点的指针域为空(用NULL或0表示),表示链表终止。链表的逻辑结构如图8.2所示。图8.2链表的逻辑结构第24页/共45页2结点结构体类型的定义结点结构体类型的定义在C语言中,定义链表结点结构的一般形式如下:struct结构体名数据成员表;struct结构体名*指针变量名;第25页/共45页3结点的动态分配结点的动态分配在C语言中,可以利用malloc函数向系统申请分配链表结点的存储空间,其形式为malloc(存储区字节数)该函数返
13、回存储区的首地址。例如,structnodeintd;structnode*next;structnode*p;p(structnode*)malloc(sizeof(structnode);释放存储区用如下函数:free(p);第26页/共45页8.4.2链表的基本运算链表的基本运算1在链表中查找指定元素在链表中查找指定元素在对链表进行插入或删除的运算中,总是首先需要找到插入或删除的位置,这就需要对链表进行扫描查找,在链表中寻找包含指定元素值的前一个结点。当找到包含指定元素的前一个结点后,就可以在该结点后插入新结点或删除该结点后的一个结点。第27页/共45页下面是在非空链表中寻找包含指定元素
14、值的前一个结点的C语言描述。structnode/*定义结点类型*/ETd;/*ET为数据元素类型名,下同*/structnode*next;/*在头指针为head的非空链表中寻找包含元素x的前一个结点p(结点p作为函数值返回)*/structnode*lookst(head,x)ETx;structnode*head;structnode*p;phead;while(pnext!NULL)&(pnext)d)!x)ppnext;return(p);第28页/共45页2链表的插入链表的插入链表的插入是指在原链表中的指定元素之前插入一个新元素。要在链表中包含元素x的结点之前插入一个新元素b。其插
15、入过程如下:(1)用malloc()函数申请取得新结点p,并置该结点的数据域为b。即令pdb。(2)在链表中寻找包含元素x的前一个结点,设该结点的存储地址为q。链表如图8.3(b)所示。(3)最后将结点p插入到结点q之后。为了实现这一步,只要改变以下两个结点的指针域内容:第29页/共45页使结点p指向包含元素x的结点(即结点q的后件结点),即令pnextqnext使结点q的指针域内容改为指向结点p,即令qnextp第30页/共45页图8.3链表的插入第31页/共45页3链表的删除链表的删除链表的删除是指在链表中删除包含指定元素的结点。为了在链表中删除包含指定元素的结点,首先要在链表中找到这个结
16、点,然后将要删除结点放回到可利用栈。要在链表中删除包含元素x的结点。其删除过程如下:(1)在链表中寻找包含元素x的前一个结点,设该结点地址为q。则包含元素x的结点地址pqnext。(2)将结点q后的结点p从链表中删除,即让结点q的指针指向包含元素x的结点p的指针指向的结点,即令qnextpnext(3)将包含元素x的结点p释放。此时,链表的删除运算完成。第32页/共45页图8.4链表的删除第33页/共45页8.5联联合合体体C语言中中的联合数据类型可以满足这种需要。联合体又称为共用体,意为各种不同数据共用同一段存储空间。与结构体类似,为了定义联合体类型变量,首先要定义联合体类型,说明该联合体类
17、型中包括哪些成员,它们各属于何数据类型,然后再定义该类型的变量。第34页/共45页定义联合体数据类型的一般形式为union联合体名成员表;例如,unionwintk;doubled;charc;定义了一个联合体类型w,包括代表整型量的成员k、代表双精度型量的成员d和代表字符型量的成员c。第35页/共45页下面对联合体类型变量作几点说明:(1)由于一个联合体变量中的各成员共用一段存储空间,因此,在任一时刻,只能有一种类型的数据存放在该变量中,即在任一时刻,只有一个成员的数据有意义,其他成员的数据是没有意义的。(2)在引用联合体变量中的成员时,必须保证数据的一致。(3)在定义联合体变量时不能为其初
18、始化,并且,联合体变量不能作为函数参数。(4)联合体类型与结构体类型可以互相嵌套,即联合体类型可以作为结构体类型的成员,结构体类型也可以作为联合体类型的成员。第36页/共45页8.6枚举类型与自定义类型名枚举类型与自定义类型名8.6.1枚举类型枚举类型 (1)先定义枚举类型,然后定义该枚举类型的变量。定义枚举类型的一般形式为enum枚举类型名枚举元素列表;其中在枚举元素列表中依次列出了该类型中所有的元素(即枚举常量),如果在定义中没有显式地给出这些元素的值,这些元素依次取值为0,1,2,。(2)在定义枚举类型的同时定义该枚举类型的变量。这种定义方法的一般形式为enum枚举类型名枚举元素列表变量
19、表;(3)直接定义枚举类型变量。这种定义方法的一般形式为enum枚举元素列表变量表;第37页/共45页在使用枚举类型数据时,要注意以下几个问题:(1)不能对枚举元素赋值,因为枚举元素本身就是常量(即枚举常量)。(2)虽然在程序中不能对枚举元素赋值,但实际上,每个枚举元素都有一个确定的整型值。(3)C语言允许将一个整型值经强制类型转换后赋给枚举类型变量。第38页/共45页8.6.2自定义类型名自定义类型名在一个C程序中,可以使用C提供的标准数据类型名(如int,char,float,double等),也可以使用用户自己定义的数据类型名(如结构体类型,联合体类型,枚举类型等)。除此之外,C语言还允
20、许用typedef声明新的类型名来代表已有的类型名,称为自定义类型名。自定义类型名的一般形式为typedef原类型名新类型名;它指定用新类型名代表原类型名。第39页/共45页8.7程序举例程序举例例例8.11设有学生情况登记表如表8.3所示。用选择排序法对该表按成绩从小到大进行排序。表8.3学生情况登记表学号num姓名name8性别sex年龄age成绩score101ZhangM1995.6102WangF1892.4103ZhaoM1985.7104LiM2096.3105GouM1990.2106LinM1891.5107MaF1798.7108ZhenM2190.1109XuM1989.
21、8110MaoF1894.9第40页/共45页其C程序如下:#defineSTUDENTstructstudentSTUDENTintnum;charname8;charsex;intage;doublescore;#includestdio.hmain()inti;voidsort();第41页/共45页staticSTUDENTstu10101,Zhang,M,19,95.6,102,Wang,F,18,92.4,103,Zhao,M,19,85.7,104,Li,M,20,96.3,105,Gou,M,19,90.2,106,Lin,M,18,91.5,107,Ma,F,17,98.7,
22、108,Zhen,M,21,90.1,109,Xu,M,19,89.8,110,Mao,F,18,94.9;第42页/共45页STUDENT*p10;for(i0;i9;i)pi&stui;printf(n);printf(No.NameSexAgeScoren);for(i0;i9;i)printf(%8d%9s%8c%8d%5.2fn,(*pi).num,(*pi).name,(*pi).sex,(*pi).age,(*pi).score);printf(n);sort(p,10);printf(No.NameSexAgeScoren);for(i0;i9;i)printf(%8d%9s%8c%8d%5.2fn,(*pi).num,(*pi).name,(*pi).sex,(*pi).age,(*pi).score);printf(n);第43页/共45页voidsort(p,n)intn;STUDENT*p;inti,j,k;STUDENT*w;for(i0;in1;i)ki;for(ji1;jn;j)if(*pj).score(*pk).score)kj;if(k!i)wpi;pipk;pkw;return;第44页/共45页感谢您的欣赏!第45页/共45页