结构体:
对齐,填充,不填充
计算大小的规律
1.每一个成员的偏移量都必须是该成员字节数大小的倍数。
第一个成员的偏移量都是0,一般可以不看
2.结构体的大小必须是该结构体成员中字节数最大的倍数。
填充的字节用[]表示
最宽字节8
1 [3] 4 8
struct X {
char a; //1
int b; //4
double c; //8
} S1;
最宽字节8
1 [7] 8 4 [4]
struct X {
char a;
double b;// 放在8的整数倍上
int c;
} S2;
结构体的大小必须是该结构体成员中字节数最大的倍数
最宽字节8
8 1 [3] 4
struct X {
double a;
char b;
int c;
} S3;
每一个成员的偏移量都必须是该成员字节数大小的倍数。
最宽字节8
8 1 [3] 4 1 [3] 4
struct X {
double a;
char b;
int c;
char d;
int e;
} S5;
每一个成员的偏移量都必须是该成员字节数大小的倍数。
最宽字节8
4 [4] 8 1 [3] 4 1 [7]
struct X {
int e;
double a;
char b;
int c;
char d;
} S6;
结构体的大小必须是该结构体成员中字节数最大的倍数
最宽字节8
1 [3] 4 8
struct X {
char a;
int b;
double c;
};
结构体嵌套
最宽字节8,struct X里面的最宽元素是8,struct Y的是1
struct X最宽元素是8字节,所有需要按8的整数倍来存放struct X
1 [7] 16
struct Y {
char a;
struct X b;
};
// __attribute((packed)),编译器选项,不填充
4 1
struct tag0 {
int a;
char b;
} __attribute((packed));
4 4
struct tag1 {
int a;
int b;
} __attribute((packed));
// 64位
4 4 8
struct tag2 {
int a;
int b;
char *c;// 指针,64位下占8个字节
} __attribute((packed));
4 4
struct tag3 {
int a;
int b;
char c[0]; // 占位符,大小为0,
} __attribute((packed));
4 4 1
struct tag4 {
int a;
int b;
char c[1]; // 字符数组,只有一个元素,占用sizeof(char),1个字节
} __attribute((packed));
// 省空间,较少内存占用
5 [3] 5 [3] 5 [3] 5 [3] 5 [3],总共5个字节
typedef struct AA {
unsigned char b1 : 5; // 只使用前5位,后3位不用
unsigned char b2 : 5;
unsigned char b3 : 5;
unsigned char b4 : 5;
unsigned char b5 : 5;
} AA;
5 5 5 5 5,占了4个字节
typedef struct BB {
unsigned int b1 : 5;
unsigned int b2 : 5;
unsigned int b3 : 5;
unsigned int b4 : 5;
unsigned int b5 : 5;
} BB;