一.结构体
结构体的自引用全部用指针来进行
<1.结构体的声明
struct tag
{
member-list;
}变量名
<2.结构体变量的定义和初始化
可以在定义变量的同时进行初始化,也可单独定义变量在进行初始化(和数组初始化基本一致).
<3.结构体的内存对齐
进行内存对齐的原因:平台原因和性能原因
1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址
处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器
需要作两次内存访问;而对齐的内存访问仅需要一次访问
内存对齐的规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的对齐数为自身的大小,也可以通过pragma pack(num)来设置对齐数的大小。
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所
有最大对齐数(含嵌套结构体的对齐数)的整数倍。
二.位段
1.位段的定义
位段的成员必须是int,unsigned int,signed in,且内部成员类型相同。
位段的成员后面会有一个冒号和数字,用来表示使用该变量的几个比特位。
位段和结构体不同,它是尽可能的减少空间,不可以跨平台。
2.位段的大小
位段内部的所有比特位相加,若和超过了本身的字节数,则还需在加一个字节,直至容下所有位段。
三.枚举
1.枚举类型的定义
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
内部元素为常量且为整形,
2.枚举的优点
增加代码的可读性和可维护性
和#define定义的标识符比较枚举有类型检查,更加严谨。
防止了命名污染(封装)
四.联合
1.联合的定义
union Un
{
char c;
int i;
};
//联合变量的定义
union Un un;
//计算连个变量的大小
2.联合体的特点
联合体内部成员共同使用一块空间,所以空间大小至少为最大成员的大小。
联合体内部的所有成员均为联合体变量的第一个成员,所有成员的地址相同。
3.联合体大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
例如:
nion Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
//下面输出的结果是什么?
printf("%d\n", sizeof(union Un1));//8
printf("%d\n", sizeof(union Un2));//16