结构体
结构体声明时,成员大小必须确定,因此不能有未定义大小的数据类型作为成员,同样也不能用函数作为结构体成员。
但是,每个系统指针类型的大小是确定的,所以可以以结构体指针或者函数指针作为结构体成员。
结构体字节对齐
结构体变量本身从4字节对齐的位置开始存放。
整个结构体所占空间还要是成员中‘占字节最大的基本数据类型’的整数倍,不够的在末尾补齐。
short类型从地址是2的倍数处开始存储,int类型从地址是4的倍数处开始存储,double类型从地址是8的倍数处开始存储,空出来的部分内存由编译器填充。
struct da
{
double a;
char b;
};
struct data //24字节 ,内部结构体对齐规则会影响外部结构体
{
struct da d; //16字节
int e; //8字节
};
struct da
{
int a;
int g;
char b;
};
struct data //24字节,外部结构体对齐规则不会影响内部结构体
{
struct da d; //12字节
char e; //4字节
double f; //8字节
};
柔性数组
在结构体内的一个数组,必须是结构体最后的一个元素,除了这个数组,结构体还必须至少有一个成员
特定形式:a[ ]或a[0]。并且这个数组不占空间,只是一个符号(代表一个常量地址)。
一般情况下,结构体内会有一个成员专门表示柔性数组的元素个数。
typedef struct
{
int len;
int arr[];
}S;
对齐指令
#pragma pack(n) //(1、2、4、8、.....)
#pragma pack()
这两个配合使用,表示一个区间,只有这个区间内的结构体按照n字节对齐。
设置为1,就是不对齐
如果n设置的小,充分利用内存空间,牺牲了速度,降低了访问效率。
如果n设置的大,提高效率、性能,牺牲了内存空间。
用这个指令指定的对齐方式和结构体自身默认对齐方式,俩者取最小的。
位字段
专用于结构体,有时侯,结构体成员表示的数据很小,就用几个位来表示。
结构体成员的类型必须是 int 或者 unsigned int,单个成员大小不能超过一个int大小(32位)
注意 : 字段不可取地址,因为地址最小单位为字节。
struct data
{
unsigned a : 1; // 1就是一个bit,范围:0~1,超出表示范围时,自动截取低位
unsigned b :