C语言入门基础第18章结构体课件.ppt

C语言入门基础第18章结构体课件.ppt

ID:57057012

大小:116.00 KB

页数:45页

时间:2020-07-30

上传者:U-5649
C语言入门基础第18章结构体课件.ppt_第1页
C语言入门基础第18章结构体课件.ppt_第2页
C语言入门基础第18章结构体课件.ppt_第3页
C语言入门基础第18章结构体课件.ppt_第4页
C语言入门基础第18章结构体课件.ppt_第5页
资源描述:

《C语言入门基础第18章结构体课件.ppt》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

第18章结构体通过本章的学习中,要重点掌握以下知识点:结构体的概念及用途;结构体类型的声明及其字长;结构体变量的定义、访问和赋值;结构体数组和结构体指针的使用。 18.1结构体结构体(struct)在C语言中用于处理多个单一数据组成的数据集合。在复杂的数据处理中,结构体是必不可少的。结构体的使用是C语言编程的一个重要部分。本节将先讨论结构体的概念,再介绍如何定义结构体变量,最后使用范例来说明结构体的字节长度。 18.1.1结构体类型的概念结构体是指包含多个单一数据的数据集合。在一些应用中,需要处理的数据往往是若干个单一数据的集合。例如,一个完整的个人信息往往需要包含姓名、年龄、性别、职业、地址、电话等信息。如果使用之前学习的简单数据类型来表示时间信息,就至少需要使用6个变量来实现,每次使用的时候都要访问至少6个变量,这是一个相当烦琐的过程。 18.1.1结构体类型的概念C语言中提供了结构体数据类型作为一个集合来处理这种复杂数据,一个结构体可以将多个单一信息结合在一起作为一个整体来使用。使用结构体时,首先要声明需要的结构体类型,其一般形式如下:struct结构体名{数据类型1结构体成员1;数据类型2结构体成员2;数据类型3结构体成员3;…};/*分号不可缺少*/ 18.1.1结构体类型的概念结构体名相当于这个结构体的标记,它与标识符struct共同组成这个结构体的名称。每一个结构体可以包含很多成员,每一个成员都有一个数据类型,这些成员可以被声明为除该结构体类型本身外的任意有效数据类型。例如,对于上述的时间信息,可以声明如下的结构体类型来处理。 18.1.1结构体类型的概念01structpersonal_infor{02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05charprofession[SIZE_P];/*职业*/06charaddress[SIZE_A];/*地址*/07chartelephone[SIZE_T];/*电话*/08};/*分号不可省略*/ 18.1.1结构体类型的概念这个结构体包含了6个结构体成员,需要注意的是,这个数据类型的名称为structpersonal_infor,而不是personal_infor。此外,这时得到的只是一个数据类型,要处理数据还要定义这种类型的变量。 18.1.2定义结构体变量声明了结构体类型后,便可以使用该类型来定义结构体变量。C语言中定义结构体变量有三种形式,其实这也是声明结构体类型的三种形式:注意:本节的结构体类型声明中的成员列表声明都与第18.1.1节中的structpersonal_infor一样。 18.1.2定义结构体变量1.声明结构体类型,并定义结构体变量例如,如果要定义personal_infor结构体变量,可以使用如下代码:01structpersonal_infor{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06};07structpersonal_inforRaul,Philip;/*定义结构体变量*/08structpersonal_inforJoe;/*再定义一个变量*/ 18.1.2定义结构体变量这种形式的定义方式可以多次定义结构体变量,如上第7行定义了Raul,在第8行可以再次使用该数据类型名来定义另一个变量Joe。需要注意的是,必须同时使用标识符struct和结构体名来定义结构体变量,如下定义语句是错误的:personal_inforErie;/*错误*/这种形式也可以在声明结构体类型的同时定义结构体变量,如下所示。01structpersonal_infor{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06}Raul,Philip;/*定义两个结构体变量*/07structpersonal_inforJoe;/*再定义一个变量*/ 18.1.2定义结构体变量2.不声明结构体类型,直接定义结构体变量这种形式的定义语句如下:01struct{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06}Raul,Philip,Joe;/*定义三个结构体变量*/ 18.1.2定义结构体变量3.使用typedef得到简化的结构体类型名,再定义结构体变量由于结构体数据类型的名字由标识符和结构体名两部分组成,书写起来名字较长,因此常常使用typedef来简化其数据类型名字,如下所示。 18.1.2定义结构体变量01typedefstruct_personal_infor{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06}personal_infor; 18.1.2定义结构体变量也可以省略该结构体名,如下所示。01typedefstruct{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06}personal_infor;得到简化的结构体数据类型名后,便可以与其他简单数据类型一样来定义结构体变量,如下所示。personal_inforRaul,Philip;personal_inforJoe; 18.1.2定义结构体变量需要注意的是,如果要在结构体内定义本指向本结构体类型空间的指针时,只能使用第一种形式,例如:01typedefstruct_personal_infor{/*声明结构体数据类型*/02charname[SIZE_N];/*姓名*/03intage;/*年龄*/04chargender;/*性别*/05…/*省略*/06struct_personal_infor*next;/*声明一个指向本结构体类型空间的指针*/07}personal_infor; 18.1.3结构体的字节长度一般的系统中,为了寻址的方便,数据在内存中存储时一般以其本身数据类型的字节长度为基本单位对齐。例如,int型在内存中是以sizeof(int)个字节对齐的,char型在内存中是以sizeof(char)个字节对齐的。而结构体数据在存储时是以其中字节长度最大的成员的字节数为基本单位对齐的。 18.1.3结构体的字节长度注意:所谓对齐,是指将内存以一个固定的字节数作为最小单位分块,分配内存时只能一块一块地分配。例如,以4字节对齐,就是将整个内存4个字节4个字节地分块,分配内存时只能4个字节4个字节地分。可以使用#pragmapack预处理命令来改变对齐规则,由于篇幅限制,在此不多做介绍。 18.1.3结构体的字节长度结构体中地成员分配的内存空间是相邻的。结构体变量所占的字节空间数,即结构体数据类型的字节长度,一般等于各个结构体成员的字节长度和。例如:structdata_type{inta;intb;intc;}; 18.1.3结构体的字节长度但是当相邻地结构体成员的字节长度长短不一时,由于内存对齐的影响,会使结构体额外占用一些空间,从而使其内存空间大于各个结构体成员的字节长度总和。 18.1.3结构体的字节长度数据类型data_type_A的字节长度为12个字节。data_type_A的内存分布如下图所示。 18.1.3结构体的字节长度v的内存分布如下图所示。 18.1.3结构体的字节长度v的内存分布如下图所示。 18.2结构体的使用结构体变量的使用与之前学习过的一般变量的使用略有不同。定义一个结构体变量后,不能直接对结构体变量进行操作,要访问结构体的内存空间,必须通过访问其成员来实现。本节将先讨论如何访问结构体成员,再介绍初始化结构体变量的方法,最后分析浅复制和深复制的原理、两者的区别以及需要注意的问题。 18.2.1访问结构体成员使用成员操作符(.)可以访问结构体成员。成员操作符是一个二元操作符,前面的操作符为结构体变量,后面的操作符为结构体成员名。其标准形式如下:结构体名.结构体成员名;例如,要访问Raul的信息,可以使用如下表达式:01Raul.name/*访问Raul的姓名*/02Raul.age/*访问Raul的年龄*/03Raul.gender/*访问Raul的性别*/04… 18.2.2初始化结构体变量使用结构体变量和其他类型变量一样,在使用前最好对其初始化。为结构体初始化的方法与数组初始化类似,可以使用一个数值序列依次为结构体成员赋值。例如为范例18-2中的raul变量初始化的语句可以如下:per_inforraul={“RaulWang”,25,‘M’};该语句依次将raul的第一个成员char型数组name赋值为”RaulWang”,第二个成员int型变量age赋值为25,将第三个成员char型变量gender赋值为’M’。 18.2.2初始化结构体变量也可以只初始化结构体变量的部分成员。此时,与初始化数组元素类似,必须对结构体变量的前面的成员连续初始化,未被初始化的成员都被自动清零,如下所示。per_inforraul={“RaulWang”};这样,raul的name成员被初始化为“RaulWang”,而未被初始化的age成员和gender成员的内存空间都被清零,即age等于0,gender等于’’。如果要将结构体变量清零,只需将其第一个成员内存初始化为全零即可。例如:per_inforraul={0}; 18.2.3浅复制和深复制结构体变量之间可以直接赋值。以范例18-3中的data_t结构体为例:01data_ta={2,2.0,‘c’,“DATA”};02data_tb=a; 18.2.3浅复制和深复制第2行语句会将b赋值为a,该赋值过程为将a的内存内容按字节依次复制给b。因此,赋值后的b的各个成员的值与a完全相同。这种按内存空间内容复制的方式为浅复制。一般情况下,浅复制的方式不会有什么问题。但是,如果结构体中含指针型成员的话,就会存在安全隐患,例如:01typedefstruct_data{02inta;03int*p;04}data_t;05intx=2;06data_ta={12,&x};07data_tb=a; 18.2.3浅复制和深复制所谓深复制,是指如果结构体含有指针型成员,复制时不是简单地复制该成员的值,而是先为该指针成员申请新的内存空间,再复制其指向的空间的内容。这样复制后新的结构体便得到一个独立的内存空间。一般来说,深度复制函数有两个部分:复制非指针成员部分和复制指针成员部分。 18.3结构体数组结构体数组就是以结构体类型为数组元素的数组。当处理一组类似个人信息之类的复杂数据时,常常需要用到结构体数组。本节先介绍定义结构体数组的方法,再介绍如何初始化结构体数组,最后通过范例来演示结构体数组的使用。 18.3.1定义结构体数组与定义结构体变量的方式相对应,定义结构体数组的方法也有三种,如下所示。 18.3.1定义结构体数组1.声明结构体类型,并定义结构体数组可以声明一个结构体类型后,再使用该结构体类型来定义结构体数组,如下所示。structperson_infor{/*定义结构体数组worker*/charname[20];intage;chargender;}worker[10];/*定义结构体数组worker*/structperson_inforfarmer[10];/*定义结构体数组farmer*/ 18.3.1定义结构体数组2.不声明结构体类型,直接定义结构体数组也可以直接定义结构体数组,如下所示。struct{charname[20];intage;chargender;}worker[10];/*定义结构体数组worker*/ 18.3.1定义结构体数组3.使用typedef还可以先使用typedef来得到结构体类型的别名,再使用该别名来定义结构体数组,如下所示。typedefstruct_person_infor{/*结构体名可以省略*/charname[20];intage;chargender;}person_infor;person_inforworker[10];/*定义结构体数组worker*/person_inforfarmer[10];/*定义结构体数组farmer*/ 18.3.2初始化结构体数组初始化结构体数组可以采用初始化值序列的形式,由于结构体本身有多个成员,因此其值序列与二维数组的初始化值序列有些类似。 18.3.2初始化结构体数组形式如下:01structperson_infor{/*声明结构体structperson_infor*/02charname[20];03intage;04chargender;05}student[4]={/*定义含有4个结构体数据的student数组*/06{“Raul”,25,‘M’},/*初始化第一个结构体元素*/07{“Joe”,23,‘F’},/*初始化第二个结构体元素*/08{“Philip”,21,‘M’},/*初始化第三个结构体元素*/09{“William”,22,‘M’}/*初始化第四个结构体元素*/10}; 18.3.2初始化结构体数组上述第6~9行为初始化值序列。其中,每行都有一对花括弧,其中均包含3个数据,用来初始化一个数组元素,即一个结构体变量。同样与其他类型数组类似,可以只初始化部分数组元素,例如:01structperson_infor{/*声明结构体structperson_infor*/02charname[20];03intage;04chargender;05}student[10]={/*定义含有10个结构体数据的student数组*/06{“Raul”,25,‘M’},/*初始化第一个结构体元素*/07{“Joe”,23,‘F’},/*初始化第二个结构体元素*/08{“Philip”},/*初始化第三个结构体元素*/09{“William”}/*初始化第四个结构体元素*/10}; 18.3.2初始化结构体数组上述语句定义了含有10个数组元素的结构体数组,但只显式初始化了4个,剩余的数组元素的内存都被自动初始化为0。其中,第8行和第9行的结构体元素的初始化序列都只包含1个字符串,那么该结构体元素的剩余空间也被自动初始化为0。也可以不指定数组容量,则其数组容量由初始化列表的值的个数来决定,如下所示。01structperson_infor{/*声明结构体structperson_infor*/02charname[20];03intage;04chargender;05}student[]={/*定义student数组*/06{“Raul”,25,‘M’},/*初始化第一个结构体元素*/07{“Joe”,23,‘F’},/*初始化第二个结构体元素*/08{“Philip”},/*初始化第三个结构体元素*/09{“William”}/*初始化第四个结构体元素*/10}; 18.3.2初始化结构体数组由于数组初始化序列中含有4个结构体值,因此该student数组的数组容量为4。另外,还可以将所有初始化值序列放在同一个花括弧内,例如:01structperson_infor{02charname[20];03intage;04chargender;05}student[4]={/*定义含有4个结构体数据的student数组*/06“Raul”,25,‘M’,/*初始化第一个结构体元素*/07“Joe”,23,‘F’,/*初始化第二个结构体元素*/08“Philip”,21,‘M’,/*初始化第三个结构体元素*/09“William”,22,‘M’/*初始化第四个结构体元素*/10}; 18.3.3结构体数组使用举例下面演示如何使用结构体数组来处理人物信息,并输出最年轻男性的人物信息。 18.4结构体指针结构体指针是使用结构体编程的重要内容。声明一个结构体指针变量,再将该变量初始化为一个存储结构体数据的内存空间的首地址后,便可以使用这个指针来访问结构体。本节先讨论指向结构体变量的指针的使用,再介绍指向堆空间的结构体指针的使用,最后将介绍指向结构体数组元素的指针的使用。 18.4.1指向结构体变量的指针定义一个指向结构体变量的指针与定义一个指向其他类型变量的指针方法基本一样,形式如下:typedefstruct{inta;charb;doublec;}my_struct;my_struct*p;使用(*p).a、(*p).b和(*p).c可以分别访问成员a、成员b和成员c。由于指针操作符的优先级比成员操作符低,因此上述访问成员的表达式中的小括号不可省略。范例18-6比较了指针操作符和成员操作符的优先级。 18.4.2指向堆空间的结构体指针可以定义一个结构体指针变量并将其指向从堆上分配的内存空间。范例18-7演示了从堆上获得结构体内存空间并使用结构体指针来访问的例子。 18.4.3指向结构体数组元素的指针将一个结构体数组元素的地址赋值给一个指针变量便可以获得一个指向结构体数组元素的指针变量。如果用来赋值的地址是一个结构体数组的元素,便可以利用该指针变量和相对偏移量的组合来访问数组中的各个结构体元素。以范例18-7中的per_infor_t结构体为例,可以使用以下方式来获得一个指向结构体数组首地址的指针变量:per_infor_tstu[10]={..};/*省略初始化列表*/per_infor_t*p=stu; 18.5综合练习1。使用结构体将复数作为一个整体,实现复数的加减运算。【提示】可以定义一个结构体,其中含有两个成员变量,分别为复数的实部和虚部。2。要求使用结构体数组设计一个程序,实现对候选人的投票统计。【提示】定义一个含字符串型成员和int型成员的结构体数组,结构体中的字符串型成员用于保存候选人名字,int型成员记录该候选人的出现次数。

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭