版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章结构类型[Return]本章学习目标掌握结构体类型和结构体变量的定义
掌握结构体变量的引用和初始化掌握结构体数组的定义和初始化掌握指向结构体类型数据的指针掌握共用体类型、变量的定义和使用掌握枚举类型的使用方法掌握使用typedef定义类型的别名本章主要内容10.1结构体类型与结构体变量的定义
10.2结构体变量的引用与初始化
10.3结构体数组
10.4指向结构体类型数据的指针
10.5共用体类型
10.6枚举类型
10.7用typedef定义类型的别名
10.1 结构体类型与结构体变量的定义10.1.1结构体类型的定义通过之前的学习我们知道C系统为了方便处理各种数据而将这些数据根据种类的不同分成了若干种类型,其中既包括整型、实型、字符型等基本类型,也包括数组这样的构造类型。但在很多情况下仅仅只有这些数据类型是不够的,在实际的应用中,经常会遇到这样的问题:几个类型不同的数据项之间有着密切地联系,它们属于同一个整体,常常被用来描述某一事物的几个特性。例如,现在编写程序需要存放学校所有教职工信息,每位教职工的信息都分为职工号、姓名、年龄、工资和籍贯等信息项,并且这些项都与某一教职工紧密相连。如表10-1所示。从上图可以看出,每位教职工都有属于自己的职工号、姓名、年龄和籍贯,并且这些信息都属于不同的数据类型,因此无法使用数组来表示(数组中的各元素必须都属于同一类型)。而如果将这些信息项分别使用相互独立的变量来表示,又无法反映各信息项之间的内在联系和整体性,并且处理起来也很不方便。因此,C语言提供了一种特殊的数据类型,这种数据类型可以把不同类型(也可以相同)的数据有机地组织成一个整体,这个整体就称为结构体类型。结构体类型是用户自定义的一种数据描述,主要由组成该结构的各个数据成员构成。其定义的一般形式如下:
struct结构体类型名
{
数据成员列表
};说明:(1)struct为关键字,不能省略,用来表示定义的数据类型为结构体类型。(2)结构体类型名是结构体类型的名字,其命名时应当遵循命名规则。(3)花括弧中的“数据成员列表”是指结构体中的各个数据成员,这些数据成员有机地结合成一个整体,构成了结构体。结构体的各个数据成员都需要定义,其定义形式为:
类型名成员变量名类型名既可以是int、char等基本类型,也可以是一个结构体类型,但是C语言规定,结构体类型在定义时不能包含自身,即不能由自己定义自己;成员变量名命名规则与普通变量名相同。(4)定义完的结构体类型和系统提供的基本类型具有同样的作用,都可以用来定义变量。(5)最后的分号不能省略。例如,表10-1的教职工信息可以定义为结构体类型:
structteacher { longnum;/*职工号*/ charname[20];/*职工姓名*/ intage;/*职工年龄*/ floatsalary;/*职工工资*/ charaddr[20];/*职工籍贯*/ };※注意:结构体类型和其他基本类型一样,只是一个数据模型,并没有具体实例,系统也不会为其分配内存单元。因此,为了使用结构体类型的数据,必须先定义结构体类型变量。10.1.2结构体类型变量的定义定义完结构体类型之后就可以定义结构体类型变量了。定义结构体类型变量一般有三种方法:1、先定义结构体类型,再定义结构体变量。其一般定义形式为:
struct类型名变量名例如: structteachert1,t2;※注意:定义结构体变量时,struct不能省略,既不能写为teachert1,t2。
2、在定义结构体类型的同时定义变量。其一般的形式为:
struct结构体类型名
{
数据成员列表
}变量名列表;
例如:
structteacher { longnum; charname[20]; intage; floatsalary; charaddr[20]; }t1,t2;※注意:在定义完变量后再加上分号。
3、省略结构体类型名,直接定义结构体变量。C语言允许使用匿名的结构体类型来定义变量,其一般形式为:
struct {
数据成员列表
}变量名列表;例如:
struct { longnum; charname[20]; intage; floatsalary; charaddr[20]; }t1,t2;这种方法虽然简单,但是程序无法再次使用这种匿名的结构体类型。关于结构体类型和变量的补充说明:(1)结构体类型与结构体变量是完全不同的概念,不能对结构体类型进行赋值、运算和输出。(2)系统在编译时,只对结构体变量分配内存空间,而对结构体类型不分配空间。(3)结构体变量在内存中所占空间大小等于该变量的所有成员变量所占内存空间之和,并且这些成员变量在内存中是顺序存放的。例如,上面定义的结构体structteacher的变量t1所占内存空间的大小为:4+20+2+4+20=50字节。(4)结构体中的成员变量既可以是基本类型变量,也可以是另一个结构体类型的变量。例如:
structdate { intyear; intmonth; intday; }; structteacher { longnum; charname[20]; intage; floatsalary; charaddr[20];
structdatebirthday;/*birthday是一个structdate类型的变量*/ };※注意:structdate的定义应该放在structteacher的定义前;结构体成员变量的类型不能是正在定义的结构体类型,既structteacher的定义中不能含有structteacher类型的变量,但可以含有正在定义的结构体类型的指针。
10.2 结构体变量的引用与初始化10.2.1结构体类型变量的引用定义完结构体变量后,就可以对这个结构体变量进行赋值和引用了。但是在引用结构体变量时,不能对变量整体进行引用,只能对结构体变量中的各成员变量逐个引用。其引用格式一般为:
结构体变量名.成员变量名这里的“.”称为成员运算符,它是左结合的,具有最高的优先级。例如,对上节中的结构体变量t1的num进行赋值:t1.num=1010;在这里需要注意的是,不能将结构体变量作为整体进行赋值和输出。例如,以下的用法是错误的:
scanf(“%ld%s%d%f%s”,&t1.num,&,&t1.age,&t1.salary,&t1.addr); printf(“%ld,%s,%d,%f,%s”,t1.num,,t1.age,t1.salary,t1.addr);如果结构体变量中又含有其他结构体类型的成员,则在引用时只能对其最低级的成员进引用。例如,对上节定义的结构体变量t1的成员birthday进行赋值:
t1.birthday.year=1978; t1.birthday.month=11; t1.birthday.day=8;结构体类型的成员变量和其他普通变量一样,也可以进行各种合法的运算。例如:
t1.num=t2.num; t1.salary=t1.salary+500;同一种类型的结构体变量之间可以整体地进行赋值。例如:t1=t2;虽说是整体赋值,实际是将t2的各成员变量的值依次赋给t1的各成员变量的。
10.2.2结构体变量的初始化结构体变量在定义的同时,可以对其各成员变量进行初始化操作。例如:struct{ longnum; charname[20]; intage; floatsalary; charaddr[20];}t1={1010,”LiBei”,”28”,”2500.0”,”Beijing”};如果结构体变量还含有其他结构体类型成员,那么在进行初始化操作时,应该按照最低层类型提供数据。例如:structdate{ intyear; intmonth; intday;};structteacher{ longnum; charname[20]; intage; structdatebirthday; floatsalary; charaddr[20]; }t1={1010,”LiBei”,”28”,1978,11,8,”2500.0”,”Beijing”};举例:/*exam10-1*/#include“stdio.h”main(){structdate{intyear; intmonth; intday;}; structteacher{ longnum; charname[20]; intage; structdatebirthday; floatsalary; charaddr[20]; }t1={1010,”LiBei”,28,1978,11,8,2500.0,”Beijing”};printf(“Num:%ld\nName:%s\nAge:%d\nBirthday:%d-%d-%d\nSalary:%f\nAddr:%s\n”,t1.num,,t1.age,t1.birthday.year,t1.birthday.month,t1.birthday.day,t1.salary,t1.addr);}Num:1010
Name:LiBeiAge:28
Birthday:1978-11-8Salary:2500.0
Addr:Beijing程序运行结果:[Return]10.3结构体数组10.3.1结构体数组的定义当需要处理多个相同结构体类型的数据时,可以使用结构体数组。结构体数组和普通数组一样,都可以顺序存放数据,只是结构体数组中的每个元素都是同一类型的结构体变量。结构体数组的定义方式和结构体变量的定义方式相同,也可以分为三种:(1)先定义类型,再定义数组。例如:
structteacher { …… }; structteachert[10];(2)在定义类型的同时,定义数组。例如:
structteacher { …… }t[10];(3)不定义类型,直接定义数组。例如:
structteacher { …… }t[10];定义完结构体数组后,就可以使用下标法来访问各数组元素了。其一般方法为:
结构体数组名[下标].成员变量名例如:
t[3].num=10020; printf(“%f”,t[3].salary);10.3.2结构体数组的初始化结构体数组的初始化方法如下: structteachert[3]={{1010,”LiBei”,28,2500.0,”Beijing”},{1011,”ZhangXia”,31,3000.0,”Shanghai”},{1012,”WangDong”,25,2800.0,”Guangzhou”}};如果在初始化的时候,没有对某个数组元素的成员变量赋初值,则系统在编译时会自动地将0赋给数值型变量,将’\0’赋给字符型变量。除此之外还可以在结构体类型定义的时候对结构体数组进行赋初值。例如: structteacher { …… }t[3]={{1010,”LiBei”,28,2500.0,”Beijing”},{1011,”ZhangXia”,31,3000.0,”Shanghai”},{1012,”WangDong”,25,2800.0,”Guangzhou”}};[Return]10.4指向结构体类型数据的指针10.4.1指向结构体变量的指针
结构体变量在内存中有对应的地址空间,其地址的值就是该变量所占内存空间的起始地址。因此我们可以定义一个指针变量来指向该结构体变量,即指针变量存放的值是结构体变量在内存中的起始地址。1、定义结构体指针变量的一般定义形式为:struct结构体类型名﹡指针变量名 例如:structteacher﹡p;定义完结构体指针变量后就可以使该变量指向同类型的结构体变量。例如: structteacher﹡p,t1; p=&t1;/*p指向t1*/2、引用和其他的指针变量一样,我们可以通过结构体指针变量间接引用它所指向变量的数据成员。其引用的方法一般有两种:(1)通过(﹡指针变量名).成员变量名的方法来引用。例如:
(﹡p).num=1001; printf(“%ld”,(﹡p).num);这里的(﹡p).num等价于t1.num。除此之外还需要注意的是,由于成员运算符“.”的优先级高于“﹡”运算符,因此指针变量名外边的括号不能省略,否则﹡p.num就等价于﹡(p.num)了。(2)通过指针变量名—>成员变量名的方法来引用(“—>”为指向成员运算符)。例如:
p—>num=1001; printf(“%ld”,p—>num);这种引用方法的效果和(﹡p).num的效果是相同的,只是采用p—>num来引用结构体变量的成员时显得更加直观和方便。例10-3输出结构体变量的各成员的值/*exam10-3*/#include“stdio.h”main(){structteacher{longnum;charname[20];intage;floatsalary;}; structteachert,﹡p;p=&t;t.num=1011;strcpy(,”LiWei”);t.age=32;t.salary=2800.0;printf(“Num:%ld\nName:%s\nAge:%d\nSalary:%f\n”,t.num,,t.age,t.salary);printf(“Num:%ld\nName:%s\nAge:%d\nSalary:%f\n”,(﹡p).num,(﹡p).name,(﹡p).age,(﹡p).salary);printf(“Num:%ld\nName:%s\nAge:%d\nSalary:%f\n”,p—>num,p—>name,p—>age,p—>salary);}[演示]10.4.2指向结构体数组的指针
和普通数组一样,对于结构体数组也可以使用指针变量来指向。如果一个指针变量存放的是一个结构体数组的首地址,则称该指针变量指向这个结构体数组。例如: structteachert[3],﹡p;p=t;C语言规定数组名代表数组元素的首地址,因此将结构体数组t的首地址赋给指针变量p,p就指向了数组t的首元素t[0],然后就可以通过指针变量的移动来访问其他的数组元素了。例如:p指向数组t的首元素,则p+1就指向数组元素t[1],依次类推,p+i指向数组元素t[i]。其指向关系见图10-1。如果需要通过指针变量来访问某个数组元素的成员变量,可以将指针变量指向该数组元素,然后通过“(﹡指针变量).成员变量”或“(﹡指针变量)—>成员变量”的方式进行访问。例10-4通过指向结构体数组的指针变量来访问结构体数组的各元素。/*exam10-4*/#include“stdio.h”main(){structteacher{ longnum; charname[20]; intage; floatsalary;}t[3]={{1010,”LiWei”,32,2500.0},{1011,”ZhangLei”,28,2000.0},{1012,”WuNan”,26,2200.0}}; structteacher﹡p;for(p=t;p<t+3;p++){printf(“Num:%ldName:%sAge:%dSalary:%f\n”,p—>num,p—>name,p—>age,p—>salary);}}[演示]※注意:由于p是一个指向structteacher类型的指针变量,因此只能指向structteacher类型的数据,而不能指向t数组元素中的某一成员。例如,以下的程序是错误的:p=&t[0].num;[Return]10.5共用体类型10.5.1共用体类型的定义
除了结构体以外,C语言还提供了一种构造类型:共用体。与结构体类似,用户也可以在共用体中定义多种不同数据类型的成员。其一般定义形式为: union共用体类型名
{
成员变量列表
};说明:union为关键字,用来声明用户定义的是一个共用体类型,而成员列表表示的是共用体类型中所含有的各成员变量。例如,定义一个共用体类型data:
uniondata { inti; charc; floatf; };共用体与结构体之间的区别共用体与结构体最大的不同在于其成员变量所占的内存长度不同:结构体变量所占的内存长度等于各成员变量所占的内存长度之和,即每个成员变量都有属于自己的内存空间;共用体变量的各成员变量都共享同一块内存空间,即共用体变量所占的内存长度等于其最长的成员变量所占的内存长度。例如,上面定义的共用体类型data含有三个成员:inti、charc、floatf,由于floatf所占的内存长度最长,因此其他的两个成员都共享f的内存空间(见图10-2),即共用体data的变量所占内存长度就等于其成员f所占的内存长度。※注意:共用体采用了覆盖技术,各成员变量互相覆盖,达到共享同一段内存的目的,这么做的最大好处是可以大大节省内存空间。10.5.1共用体变量的定义
1、先定义共用体类型,再定义共用体变量。其一般定义形式为:
union类型名变量名例如:uniondataa,b;2、在定义共用体类型的同时定义变量。其一般的形式为:
union共用体类型名
{
成员列表
}变量名列表;例如:
uniondata { inti; charc; floatf; }a,b;3、省略共用体类型名,直接定义变量。
union {
成员列表
}变量名列表;例如:
union { inti; charc; floatf; }a,b;10.5.2共用体变量的引用
定义完共用体变量后,就可以对该变量进行引用了。共用体变量的引用和结构体变量的引用方式类似,但是不能引用共用体变量整体,而只能引用共用体变量中的成员。例如,引用共用体变量a中的成员:
scanf(“%d”,&a.i); printf(“%d”,a.i);在共用体变量的引用时,应该注意以下几点:(1)由于共用体变量的所有成员都共用同一内存,因此在某一时刻只能存放其中的一个成员,即某一时刻只有一个成员起作用,而其他的成员都不起作用。例如,在执行完以下语句后:
a.i=10; a.c=’d’; a.f=14.8;共用体所占的内存中存放的数据是14.8。因此可以看出,共用体变量在存放成员时采用的是覆盖技术,即在共用体变量中有意义的成员是最后一次存放的成员,任何新数据的存入都会覆盖掉原有的数据。(2)不能对共用体变量名赋值,也不能在定义共用体变量时对共用体变量进行初始化。例如,以下程序是错误的:
union { inti; charc; floatf; }a={10,’a’,5.6};(3)可以通过指针变量引用共用体变量中的成员。例如:
uniondata﹡p,a; p=&a; p—>i=10;(4)不能将共用体变量作为函数参数,函数也不能返回共用体变量。(5)结构体类型和共用体类型在定义时可以互相嵌套。※共用体变量最大的用途是将不可能同时出现的数据项放在同一段内存当中,从而达到节省内存空间的目的。
[Return]10.6枚举类型在实际的应用中,某些变量的取值范围可能很小,可能只有仅仅几个值。例如表示方向、颜色、一周中的周一至周日等。C语言为了增加程序的可读性,在ANSIC标准后加入了“枚举”类型,在这里枚举的意思是将某种变量可能取的值一一列举出来,因此如果一个变量被定义成枚举类型,那么该变量所能取的值只能是枚举类型中所列出的值。枚举类型的一般定义形式如下:
enum枚举类型名{枚举元素1,枚举元素2,…,枚举元素n};例如:
enumcolor{red,green,blue};以上定义了一个枚举类型color,根据该类型可以定义枚举变量,枚举变量的取值范围只能是“red、green、blue”中的某一值。
枚举变量的定义形式可以分为三种:(1)先定义枚举类型后定义枚举变量。例如:
enumcolor{red,green,blue}; colora,b;(2)定义枚举类型的同时定义变量。例如:
enumcolor{red,green,blue}a,b;(3)定义匿名枚举变量。例如:
enum{red,green,blue}a,b;
当使用枚举变量时,需要注意以下几点:(1)在给枚举变量赋值时,只能将定义枚举类型时所列出的元素值赋给该变量。例如:
a=red; b=blue;(2)枚举类型所列出的元素值并不是字符串,而是整型常量,并且这些常量都是有值的,C语言在进行编译时,会按照定义的顺序将它们的值置为0、1、2、…,因此枚举元素又通常被称为枚举常量。例如,上面定义的枚举类型color中各枚举常量的值分别为:red为0,green为1,blue为2。并且这些枚举常量的值还可以以整数的形式输出。例如:
colora; a=green; printf(“%d”,a);/*输出的结果为2*/(3)不能将非枚举常量之外的值赋给枚举变量。例如,以下语句是错误的:a=3;(4)枚举常量可以参与整数运算,可以进行算术、关系等运算。例如:
if(red>green) prinf(“right!”);※从上面可以看出,枚举常量实际就是整型常量,那么它们还有什么必要存在呢?实际上使用枚举类型主要能带来两点好处:一是枚举常量限定了变量的取值范围。例如,上面定义的枚举变量a只能取red,green和blue其中之一的值;再次使用枚举常量可以增加程序的可读性。例如,定义一个含有每周七天的枚举类型:
enumweek{mon,tue,wed,thu,fri,sat,sun}today;在这里使用today=mon;就要比today=1;的可读性要强的多。
例10-6枚举类应用举例。/*exam10-6*/#include“stdio.h”main(){enumcolor{red,green,blue,black};enumcolorc;for(c=red;c<=black;c++){ if(c==red)printf(“Itisred\n”); elseif(c==green) pri
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年全新技术支持服务协议样本版B版
- 2024年国际货运责任明确协议样式版B版
- 2024MCN商务合作合同
- 2024年业务拓展合伙合作合同一
- 2024学校宿舍承包合同范本
- 2024年度大型商场智能化改造项目实施合同
- 江南大学《表面活性剂应用技术》2023-2024学年第一学期期末试卷
- 《浅谈爱滋病》课件
- 2024专业包工不包料工程承包合同版B版
- 2024年企业员工订餐服务协议范本版B版
- (2024年)健康养生养生保健课件
- 《波士顿公园系统》课件
- 《口香糖加工工艺》课件
- 《养老护理员》-课件:老年人安全防范及相关知识
- 渭南开沃新能源汽车有限公司改装车建设项目环境影响报告
- 校园水景观调研报告
- 2024年建筑工程行业的合规管理
- 概率论在金融学中的应用
- 山东省威海市环翠区2022-2023学年九年级上学期期末数学试题
- 服设职业生涯规划书
- 社会工作伦理课件
评论
0/150
提交评论