今天聊一下结构体。
前言
结构体是用来描述复杂数据类型的自定义数据类型。
C语言是一门强数据类型语言,数据类型有int,long,short等整数类型,float,double等浮点数类型,char字符类型等。但是为了描述复杂事物,这些基本数据类型是不足以承担这项任务的。
于是出现了结构体,它允许我们将基本数据类型组合起来,形成一个新的复杂数据类型。
一、结构体基础
C语言中用于描述结构体的关键字是struct,声明一个结构体的示例如下
struct Stu{
int age;
char name[20];
float score;
};
在这个栗子里,我们定义了一个名为Stu的结构体,由三个成员变量age,name,score组成。
这是最常见的定义方式。除此之外,还有匿名结构体的声明。
struct{
int age;
char name[20];
float score;
} Stu;
在这个栗子里,结构体没有类型名称。在定义结构体的时候直接创建了一个结构体变量Stu。
值得注意的是,即使两个匿名结构体类型的成员变量完全相同,也会被解析为不同的类型。
结构体的初始化方式为依序赋值。也可以通过.操作符指定需要赋值的对象。
二、结构体自引用
结构体可以通过自引用的方式进行链接。自引用的媒介为指针。如以下利用结构体定义的链表节点。
struct Node{
int data;
struct Node* next;
};
三、结构体内存对齐
这里先引入对齐数的概念。计算机读写内存并不是逐个操作的,而是遵循一定的规律,以4个或者8个等为一个单元进行读写。如果一个大小为8字节的数据卡在了3和4之间,会导致计算机读写效率下降。在结构体的变量中,内存的使用是大体连续的,但可能因为内存对齐减少一部分可用空间。
对齐数,在不同的编译器里有不同的解释。在vs中,对齐数就是8和成员变量大小中的较小值。
成员变量必须对齐到对齐数的整数倍处。结构体的总大小必须为最大对齐数的整数倍。
结构体嵌套结构体时,即结构体作为成员变量,对齐数为被嵌套结构体的成员变量的最大对齐数。
内存对齐本质上是通过牺牲部分可用空间来提高运行效率。实际生产中可以通过将体积较小的变量放置在一起来降低空间损耗。
默认对齐数可以通过预处理命令进行修改。
四、结构体传参
结构体是由简单数据类型复合而成的复杂数据类型,在进行传参的时候应该避免直接传递结构体。函数形参是实参的一份临时拷贝,直接传递结构体容易造成空间浪费,降低系统性能。应该传递指针。
在函数内部可以通过箭头操作符访问结构体成员。
五、联合体
联合体内所有数据成员共享数据空间。
对于一类数据,具有一些公共属性,具有一些私有属性。将私有属性放置在联合体中可以减少内存消耗。也可以用于数据存储细节的观察学习。
联合体的大小也满足最大对齐数的整数倍。
关键字为union。其他使用方法与struct相同。
六、枚举
枚举也是一种数据类型。关键字为enum。
示例如下
enum Day{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
大括号中的是枚举可能取值,也叫枚举常量。
每一个枚举常量都代表一个整数值,从0开始依次增大。
也可以给枚举常量赋值。赋值之后,该枚举常量之后的枚举常量在此基础上依次增大。
枚举具有作用域。