ch08 结构.ppt
第8章 结构2023/1/27目录8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表2C+实用教程8.1 结构类型结构类型是从结构类型是从C语言继承下来的一种构造数语言继承下来的一种构造数据类型,它是由多种类型的数据(变量)据类型,它是由多种类型的数据(变量)组成的整体。组成的整体。组成结构类型的各个分量称为结构的数据组成结构类型的各个分量称为结构的数据成员成员(简称成员,或称成员变量)。(简称成员,或称成员变量)。3C+实用教程8.1.1 结构类型声明定义结构类型定义结构类型 struct 结构类型名结构类型名;.;struct STUDENTintno;floatscore3;floatedit3;floattotal,ave;floatalledit;4C+实用教程说明:结构类型名应是一个合法有效的标识符,结构类型名应是一个合法有效的标识符,若该结构类型变量以后不再定义,结构类若该结构类型变量以后不再定义,结构类型名可省略。型名可省略。结构类型名是区分不同类型的标识。结构类型名是区分不同类型的标识。结构类型名通常用大写字母表示,以便与结构类型名通常用大写字母表示,以便与其他类型名区别。其他类型名区别。结构类型成员还可以是另一个已定义的结结构类型成员还可以是另一个已定义的结构类型。构类型。struct POINTintx,y;struct RECTPOINT ptLeftTop;int nWidth;int nHeight;5C+实用教程8.1.2 定义结构类型变量结构类型变量的定义结构类型变量的定义声明之后定义方式声明之后定义方式声明之时定义方式声明之时定义方式直接(一次性)定义方式直接(一次性)定义方式结构类型变量的初始化结构类型变量的初始化在定义的结构类型变量后面加上在定义的结构类型变量后面加上“=初值列表初值列表;”可适当增加花括号,增加可读性。可适当增加花括号,增加可读性。struct ,;struct STUDENTintno;floatscore3;floatedit3;floattotal,ave;floatalledit;struct STUDENT stu1,stu2;struct STUDENTintno;floatscore3;floatedit3;floattotal,ave;floatalledit;stu1,stu2;struct intno;floatscore3;floatedit3;floattotal,ave;floatalledit;stu1,stu2;STUDENT stu1=1001,90,95,75,3,2,2;STUDENT stu1=1001,90,95,75,3,2,2;6C+实用教程8.1.3 结构类型变量的引用格式格式规则规则只能引用结构类型变量中的成员变量。只能引用结构类型变量中的成员变量。若成员本身又是一个结构类型变量,引用时需若成员本身又是一个结构类型变量,引用时需要用多个成员运算符一级一级地找到最低一级要用多个成员运算符一级一级地找到最低一级的成员。的成员。多数情况下,结构类型相同的变量之间可以直多数情况下,结构类型相同的变量之间可以直接赋值,这种赋值等效于各个成员的依次赋值。接赋值,这种赋值等效于各个成员的依次赋值。.“.”是成员运算符,它的优是成员运算符,它的优先级仅次于域运算符先级仅次于域运算符“:”struct POINTintx,y;spot=20,30;coutspot.xspot.y;struct RECTPOINT ptLeftTop;POINT ptRightDown;rc=10,20,40,50;coutrc.ptLeftTop.xrc.ptLeftTop.y;POINT pt1=10,20;POINT pt2=pt1;coutpt2.xtpt2.y;7C+实用教程第8章 结构8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表8C+实用教程8.2 结构数组由结构类型的元素组成的数组称为由结构类型的元素组成的数组称为结构数结构数组组。1.结构数组的定义结构数组的定义定义结构数组只要在定义结构变量的基础上增定义结构数组只要在定义结构变量的基础上增加维数说明即可。加维数说明即可。2.结构数组的初始化结构数组的初始化其方法与数组相同。但要注意,由于结构类型其方法与数组相同。但要注意,由于结构类型声明的是一条记录信息,一维结构数组初始化声明的是一条记录信息,一维结构数组初始化的形式应与二维普通数组相同。的形式应与二维普通数组相同。3.结构数组元素的引用结构数组元素的引用 struct POINTint x,y;POINT pt110,pt21020;.9C+实用教程例例Ex_StructStu 用结构数组输出平用结构数组输出平均成绩最高的记录。均成绩最高的记录。10C+实用教程例:1.struct STUDENT 2.3.int no;/学号学号4.float score3;/三门课程成绩三门课程成绩5.float edit3;/三门课程的学分三门课程的学分6.float total,ave;/总成绩和平均成绩总成绩和平均成绩7.float alledit;/总学分总学分8.;9.STUDENT stu3=1001,90,95,75,3,2,2,10.1002,80,90,78,3,2,2,11.1003,75,80,72,3,2,2;11C+实用教程8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表12C+实用教程8.3 结构与函数结构即可以作为函数的形参和实参,也可结构即可以作为函数的形参和实参,也可以作为函数的返回值。以作为函数的返回值。8.3.1 传递结构参数传递结构参数当结构类型变量作为函数的参数时,它与普通当结构类型变量作为函数的参数时,它与普通变量一样,由于结构类型变量不是地址,因此变量一样,由于结构类型变量不是地址,因此这种传递是这种传递是值传递值传递方式,整个结构都将被复制方式,整个结构都将被复制到形参中。到形参中。若函数传递的是结构数组,由于结构数组名是若函数传递的是结构数组,由于结构数组名是指针常量,因而是指针常量,因而是地址传递地址传递方式,函数中对形方式,函数中对形参内容的改变必将影响实参。参内容的改变必将影响实参。13C+实用教程例Ex_StructValue 传递结构参数示例1.#include 2.using namespace std;3.struct PERSON 4.5.int age;6.float weight;7.char name25;8.;9.void print(PERSON one);10.int main()11.12.PERSON all=20,60,Zhang,28,50,Fang,13.33,78,Ding,19,65,Chen;14.int n=sizeof(all)/sizeof(PERSON);/计算元素个数计算元素个数15.for(int i=0;in;i+)print(alli);16.return 0;17.void print(PERSON one)coutone.name t one.aget one.weight endl;14C+实用教程例Ex_StructArr 传递结构数组示例1.void sort(PERSON all,int n)2./用选择法按姓名从小到大排序用选择法按姓名从小到大排序3.intpos;4.PERSON min;5.for(int i=0;in-1;i+)6.7.min=alli;pos=i;8.for(j=i+1;jn;j+)9.if(strcmp(allj.name,min.name)0)10.min=allj;pos=j;11.allpos=alli;alli=min;12.13.15C+实用教程8.3 结构与函数结构即可以作为函数的形参和实参,也可结构即可以作为函数的形参和实参,也可以作为函数的返回值。以作为函数的返回值。8.3.2 返回结构返回结构16C+实用教程例Ex_StructRes 返回结构示例1.#include 2.using namespace std;3.struct PERSON 4.5.int age;6.float weight;7.char name25;8.;9.void print(PERSON one);10.PERSON input(void);11.int main()12.13.PERSON all4;int i;14.for(i=0;i4;i+)alli=input();15.for(i=0;i4;i+)print(alli);16.return 0;17.PERSON input(void)PERSON temp;couttemp.name temp.age temp.weight;return temp;17C+实用教程8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表18C+实用教程8.4 结构指针当定义一个指针变量的数据类型是结构类当定义一个指针变量的数据类型是结构类型时,这样的指针变量称为型时,这样的指针变量称为结构指针变量结构指针变量。结构指针变量的结构指针变量的定义定义结构指针变量的结构指针变量的赋值和初始化赋值和初始化结构指针变量的结构指针变量的成员引用成员引用struct POINT int x,y;POINT *pt;struct POINT int x,y;POINT pt1,pt2;POINT *p1=&pt1;POINT *p2=(POINT*)&pt2.x;成员运算符成员运算符“-”由减号由减号和大于号组成,中间不能和大于号组成,中间不能有空格,其左边操作数必有空格,其左边操作数必须是一个结构指针。须是一个结构指针。struct POINT int x,y;POINT pt,*p=&pt;(*p).x=20;p-y=10;struct PERSON int age;char sex;float weight;char name25;PERSON many10,*pp;pp=many;(pp+i)-name=“LiMing”;19C+实用教程例Ex_StructPointer 结构指针变量 1.#include 2.#include 3.using namespace std;4.struct PERSON 5.6.int age;7.char sex;8.float weight;9.char name25;10.;1.int main()2.3.struct PERSON one;4.struct PERSON*p;5.p=&one;/p指向指向one6.p-age=32;7.p-sex=M;8.p-weight=(float)80.2;9.strcpy(p-name,LiMing);10.cout姓名:姓名:(*p).nameendl;11.cout姓别:姓别:(*p).sexendl;12.cout年龄:年龄:(*p).ageendl;13.cout体重体重(kg):(*p).weightendl;14.return 0;15.20C+实用教程8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表21C+实用教程8.5 联合C+继承继承C语言的联合概念。语言的联合概念。联合(联合(union),又称共用,是,又称共用,是C+另一种另一种构造数据类型。构造数据类型。联合类型的定义和操作与结构类型几乎相同。联合类型的定义和操作与结构类型几乎相同。不同的是,联合类型中的成员变量共用同一块不同的是,联合类型中的成员变量共用同一块内存空间。内存空间。22C+实用教程8.5.1 联合的声明存储空间分配:存储空间分配:8字节字节 union ONE3ALL int iValue;longlValue;doubledValue;union ONE3ALL u1,u2;联联合合 体体 1 2 3 4 5 6 7 8iValuelValuedValue23C+实用教程8.5.2 联合类型变量的定义和使用当一个联合类型变量定义之后,就可引用当一个联合类型变量定义之后,就可引用这个变量,引用的规则与结构变量相同。这个变量,引用的规则与结构变量相同。例例Ex_Union 联合类型变量的定义和使用联合类型变量的定义和使用24C+实用教程8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表25C+实用教程8.6 使用typedef1.为基本类型添加新的类型名为基本类型添加新的类型名typedef ;2.为数组类型增加新的类型名为数组类型增加新的类型名typedef ;3.为结构类型名增加新的类型名为结构类型名增加新的类型名typedef struct 结构类型名结构类型名;26C+实用教程4.为指针类型名增加新的类型名称为指针类型名增加新的类型名称由于指针类型不容易理解,因此由于指针类型不容易理解,因此typedef常用常用于指针类型名的重新命名。例如:于指针类型名的重新命名。例如:typedef int*PInt;typedef float*PFloat;typedef char*String;PInt a,b;/等效于等效于int*a,*b;8.6 使用typedef27C+实用教程第8章 结构8.1 结构类型结构类型8.2 结构数组结构数组8.3 结构与函数结构与函数8.4 结构指针结构指针8.5 联合联合8.6 使用使用typedef8.7 简单链表简单链表28C+实用教程8.7.1 链表概述链表是一种动态数据结构,它的特点是用链表是一种动态数据结构,它的特点是用一组任意的存储单元(可以是连续的,也一组任意的存储单元(可以是连续的,也可以是不连续的)存放数据元素。可以是不连续的)存放数据元素。链表是一种递归数据结构。链表是一种递归数据结构。struct NODE int data;NODE *next;NODE *head,*p;29C+实用教程1.建立链表建立链表新建链表的过程:新建链表的过程:1.链头指针:链头指针:ph=02.链尾指针:链尾指针:pe03.然后在链表中加入结点然后在链表中加入结点(append):4.分配内存单元,地址分配内存单元,地址p;成功执行步骤成功执行步骤2,否则输出出,否则输出出错信息后执行步骤错信息后执行步骤45.是空链?是空链:头指针是空链?是空链:头指针ph=p,否则原尾指针否则原尾指针 pe的下的下一个成员地址是一个成员地址是p6.p是链尾:是链尾:p-next=0,pe=p7.结束结束 8.7.2 链表的创建和遍历30C+实用教程创建链表的过程创建链表的过程 8.7.2 链表的创建和遍历31C+实用教程2.遍历与输出链表遍历与输出链表输出链表的过程:输出链表的过程:1.链头指针:链头指针:ph2.链尾指针:链尾指针:pe3.p=ph,执行执行24.p=0?(是空链?是空链?),是执行,是执行4;否则执行;否则执行35.输出:输出:*p,p=p-next,重复步骤重复步骤2 6.结束结束 8.7.2 链表的创建和遍历32C+实用教程1.删除结点:删除结点:p:当前结点指针,当前结点指针,p0:前一结点指针前一结点指针1.ph=0?(空链?空链?),是输出,是输出“空链空链”,执行,执行8;否则;否则p=ph,执行执行22.输入被删除结点的信息输入被删除结点的信息3.p-成员值成员值=输入信息?,是执行输入信息?,是执行5,否则执行,否则执行44.4p0=p,p=p-next,p=0?(链结束?链结束?),是输出,是输出“找找不到被删除结点不到被删除结点”,然后执行,然后执行8,否则重复步骤,否则重复步骤35.删除该节点:删除该节点:p=ph?(链首结点链首结点),是,是,ph=p-next,然后执行然后执行7;否则执行;否则执行66.p0-next=p-next7.释放释放p所指向的内存单元所指向的内存单元8.结束结束 8.7.3 链表的删除33C+实用教程2.删除整个链表删除整个链表删除整个链表最简单的方法是循环删除并释放第一个删除整个链表最简单的方法是循环删除并释放第一个结点结点,如下面的程序代码:如下面的程序代码:1.void DeleteAll(NODE*head)2.3.NODE *p=*head;4.while(*head)5.6.*head=p-next;delete p;p=*head;7.8.8.7.3 链表的删除34C+实用教程8.7.4 链表结点的插入和添加 链表结点的插入链表结点的插入如果要在链表结点如果要在链表结点a之前插入新结点之前插入新结点b,需要考,需要考虑下列虑下列4种情况:种情况:35C+实用教程插入结点:插入结点:1.Ph=0?(空链?空链?),调用,调用“添加结点函数添加结点函数”(append(),调用毕执行调用毕执行9;否则;否则p=ph,p0=ph(p0=插入的定位结插入的定位结点的前一个结点的地址点的前一个结点的地址),执行,执行22.输入插入点信息输入插入点信息3.p-成员值成员值=输入信息?,是执行输入信息?,是执行5,否则执行,否则执行44.4p0=p,p=p-next,p=0?(链结束?链结束?),是输出,是输出“找找不到插入结点不到插入结点”,然后执行,然后执行8,否则重复步骤,否则重复步骤35.pp=新分配内存单元的地址,新分配内存单元的地址,pp!=0?(分配成功?分配成功?),是输出是输出“分配失败分配失败”,然后执行,然后执行8,否则执行,否则执行66.p=ph?(链首结点链首结点),是:,是:ph=pp,pp-next=p,然后然后执行执行8;否则执行;否则执行77.p0-next=pp,pp-next=p8.结束结束 8.7.4 链表结点的插入和添加 36C+实用教程8.7.5 用链表求解Josephus问题Josephus问题中,一圈小孩用环链表来表问题中,一圈小孩用环链表来表示是最直接的了。所谓环链表,就是将链示是最直接的了。所谓环链表,就是将链表的最后一个结点的指针域指向头指针,表的最后一个结点的指针域指向头指针,形成一个环,如所示。形成一个环,如所示。37C+实用教程小结结构类型结构类型声明声明定义定义引用引用联合类型联合类型结构类型与联合类型比较结构类型与联合类型比较typedef38C+实用教程作业P.2033,439C+实用教程