结构体、共用体、枚举和位域
结构体声明、定义与存储形式
-
结构体在C语言中用于处理多个单一数据组成的数据集合。一个结构体可以将多个单一信息结合在一起作为一个整体来使用。与整型等简单数据类型一样,使用前需要进行声明:
struct 结构体名{ 数据类型1 结构体成员1; 数据类型2 结构体成员2; 数据类型3 结构体成员3;
… };这个数据类型名称为:struct 结构体名 -
声明之后,便可以使用该类型来定义结构体变量:struct 结构体名 变量名
-
结构体的存储形式:一般的系统中,为了寻址的方便,数据在内存中存储时,一般以其本身数据类型的字节长度为基本单位对齐。而结构体数据在存储时是以其中字节长度最大的成员的字节数为基本单位对齐的。结构体中的成员分配的内存空间是相邻的。
-
为了提高程序可读性,最好在 main 函数外声明结构体数据类型。
结构体的应用
- 访问结构体成员:使用成员操作符(.)可以访问结构体成员。前面的操作符为结构体变量,后面的操作符为结构体成员名。形式:
结构体名.结构体成员名; - 初始化结构体变量:与其他类型变量一样,使用前最好进行初始化。方法是可以使用一个数值序列依次为结构体成员赋值。也可以只初始化部分成员,未被初始化的成员都被自动清零。
- 结构体变量之间还可以直接赋值,比如data_t b = a;这句话将a的内存内容按字节依次赋值给b(浅复制)。但是,如果结构体中含指针型成员的话,就会存在安全隐患,这时候要采用深复制的方式来赋值。
结构体数组
结构体数组就是结构体类型变量为数组元素的数组。定义和初始化方法同上。
结构体指针
声明一个结构体指针变量,然后再将变量初始化为一个存储结构体数据的内存空间的首地址后,便可以使用这个指针来访问结构体了。
结构体小结
结构体的名称较长,可以使用 typedef 来得到简化的别名。
最好不要使用对于含有指针性成员的结构体变量作为函数形参或返回值。
共用体
顾名思义,共用体可以使几个不同成员共享同一块内存。优点:节省内存空间,简化复杂数据的处理。
首先声明:union 共用体名{
数据类型名 成员名1;
数据类型名 成员名2;
数据类型名 成员名3;
…
};
一个共用体类型的字节长度为占用内存空间最多的成员变量的字节长度。
然后定义:使用声明后的共用体类型定义共用体变量。
注意:由于共用体变量实际上只有一个有效成员,所以只能使用含一个值的序列进行初始化;另外,不可以直接为共用体变量进行赋值,需要通过赋值其成员来改变共用体的赋值空间;由于共用体中的所有成员共享一块空间,因此,对任意成员的赋值都会影响其他成员的值,也不要在共用体中包含指针成员,尤其不要包含指向堆空间的指针成员。
枚举
枚举类型是一组相关数据的集合,它可以在定义常量的同时,将这些常量结合在一个集中加强彼此的关系。其声明如下:
enum 枚举类型名{
枚举成员1;
枚举成员2;
枚举成员3;
…
}
定义:enum 枚举类型名 枚举变量 = 常量;
位域
主要处理占用一个或几个二进制位的信息,它允许在结构体内以位为单位将其空间划分为多个区域,并将其分配给结构体的各个成员。形式如下:
struct 结构体名 {
unsigned 位域成员1:常量1;
unsigned 位域成员2:常量2;
int 位域成员3:常量3;
int 位域成员4:常量4;
…
};
位域成员的类型只能是 int 型或 unsigned 型。常量值指定了该区域所占的位数,且该数值不能大于其数据类型所占位数。
存储形式:正常情况下,位域中的位域成员的内存是相邻的。但是,如果位域成员所占空间是不能跨两个基本位域单元的。
以上就是三种高级数据类型:结构体、共用体和枚举了。本章学习的数据类型的名称都较长,可以使用 typedef 来得到简化的别名。