其作用是以空间换时间(涉及硬件操作)
内存补齐:
结构的总字节数,必须是其最大成员大小的整数倍,超过4字节的按照4字节算(32位系统),为此可能需要在末尾填充若干字节。
struct Y {
int a;
char b;
short c;
char d;
} y;
内存对齐:
结构中每个成员的起始地址,必须是其自身大小的整数倍,超过4字节的按4字节算(针对32位操作系统),为此可能需要在中间填充若干字节。
struct A{
char a;
short b;
char c;
int d;
};
内存 |----|----|----|----|----|----|----|----|--------------|
起始地址 0 1 2 3 4 5 6 7 8 4字节
内存大小 1 1 1 1 1 1 1 1 4字节
a 填充 b b c 填 填 填 d
printf("sizeof(struct A)=%u\n",sizeof(struct A)); 默认答案是12字节。
以如下举例:
64位系统
struct A {
int a; // i i i i
char b;// i i i i,为double8字节对齐
double c; // i i i i i i i i
char d; // i i i i i i i i //补齐
};
sizeof(struct A) = 24
32位系统 超过4字节按照4字节来算
struct A{
int a; // i i i i
char b; // i i i i
double c; // i i i i i i i i
char d; // i i i i
};
sizeof(struct A) =20
若想直接查看就用指针查看地址
代码如下:
#include <stdio.h>
struct A {
char buf[2]; //CCXX
int a;//IIII
};//8
struct B {
char c;//CX
short s[2];//SSSSXX
int i;//IIII
};//12
#pragma pack(1) //让gcc强制从代码的这个地方开始往后所有代码按照1字节进行对齐和补齐进行编译
struct C {
char c;//C
short s[2];//SSSS
int i;//IIII
};//9
#pragma pack() //让gcc强制从代码的这个地方开始往后所有代码恢复到默认的对齐和补齐方式进行编译
struct D {
int i;//IIII
char c;//CXXX
};//8
struct E {
double d;//DDDDDDDD
char c;//CXXXXXXX(64):16, CXXX(32):12
};
int main(void) {
printf("%lu\n", sizeof(struct A));
printf("%lu\n", sizeof(struct B));
printf("%lu\n", sizeof(struct C));
printf("%lu\n", sizeof(struct D));
printf("%lu\n", sizeof(struct E));
struct A sa;
printf("%p, %p\n", sa.buf, &sa.a);
return 0;
}