struct xx {
long long a;
char b;
int c;
char d[2];
static int e;
};

int main(){
struct xx x;
printf("%ld\n", sizeof(x.a)); //8
printf("%ld\n", sizeof(x.b)); //1 + 3 = 4
printf("%ld\n", sizeof(x.c)); //4
printf("%ld\n", sizeof(x.d)); //2 + 6 = 8
printf("%ld\n", sizeof(x.e)); //4
printf("%ld\n", sizeof(x)); //24 = 8 + 4 + 4 + 8

printf("%p\n", &(x.a)); //007DFCEC
printf("%p\n", &(x.b)); //007DFCF4
printf("%p\n", &(x.c)); //007DFCF8
printf("%p\n", &(x.d[0])); //007DFCFC
printf("%p\n", &(x.d[1])); //007DFCFD
printf("%p\n", &(x.e)); //由于static变量分配在全局区,不在结构体的空间内,这一句报错
}

只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的

C语言结构体内存对齐_c语言

typedef struct{
char a;
int b;
short c;
}A;

int main(){
A aa;
printf("%ld\n", sizeof(aa.a));//1 + 3
printf("%ld\n", sizeof(aa.b));//4
printf("%ld\n", sizeof(aa.c));//2 + 2
printf("%ld\n", sizeof(aa));//12

printf("%p\n", &(aa.a));//00CFFCEC
printf("%p\n", &(aa.b));//00CFFCF0
printf("%p\n", &(aa.c));//00CFFCF4
}

C语言结构体内存对齐_f5_02

typedef struct
{
char a;
short b;
int c;
}B;

int main(){
B bb;
printf("%ld\n", sizeof(bb.a));//1 + 1
printf("%ld\n", sizeof(bb.b));//2
printf("%ld\n", sizeof(bb.c));//4
printf("%ld\n", sizeof(bb));//8

printf("%p\n", &(bb.a));//00E6F858
printf("%p\n", &(bb.b));//00E6F85A
printf("%p\n", &(bb.c));//00E6F85C
}

C语言结构体内存对齐_c语言_03

struct Date {
char a;
int b;
long long c;
char d;
};

int main() {
struct Date date[2][10];
struct Date dd;

printf("%ld\n", sizeof(dd.a));//1 + 3
printf("%ld\n", sizeof(dd.b));//4
printf("%ld\n", sizeof(dd.c));//8
printf("%ld\n", sizeof(dd.d));//1 + 7
printf("%ld\n", sizeof(struct Date));//24

printf("%p\n", &(dd.a));//0093F9A8
printf("%p\n", &(dd.b));//0093F9AC
printf("%p\n", &(dd.c));//0093F9B0
printf("%p\n", &(dd.d));//0093F9B8

// 说明结构体最后的d占了8字节
printf("%p\n", &(date[0][0].d)); // 00F5F78C
printf("%p\n", &(date[0][1].a)); // 00F5F794
}

C语言结构体内存对齐_c语言_04

struct sdate {
int year;
int month;
int day;
};

struct Student {
char s_id[10];
char s_name[8];
struct sdate birthday;
double grade;
};

int main(){
printf("%ld\n", sizeof(struct Student));//40
return 0;
}

C语言结构体内存对齐_f5_05

struct Person {
const char* name;
int age;
};

int main(){
printf("%ld\n", sizeof(struct Person)); // 8
struct Person p = {"shen12", 22};
printf("%ld\n", sizeof(p)); // 8
return 0;
}

C语言结构体内存对齐_静态数据成员_06

空结构体

struct x{

};

int main(){
// C++ : 1,其实是占位符
// C : 0
printf("%ld\n", sizeof(struct x));
return 0;
}

不含任何成员变量且没有虚函数的存在:sizeof(对象)=1。解释——虽然什么都没有存,但是如果完全不分配空间的话,先定义一个对象再定义一个对象,如果对象不占空间的话,那么这两个对象起始地址就会一样,(除了联合体类型外,都不允许发生这样的情况)。分配最小的单位是1个字节——就是为了占地方,没有其他作用

C语言结构体内存对齐_静态数据成员_07

pragma pack(n)改变内存对齐方式

C语言结构体内存对齐_c++_08


C语言结构体内存对齐_静态数据成员_09

C语言结构体内存对齐_静态数据成员_10


关于改变内存对齐方式总结:

C语言结构体内存对齐_f5_11

总结:

C语言结构体内存对齐_f5_12

个人总结: 当放入一个结构体成员时,该成员的的起始地址相对于结构体首地址的偏移量必须是该成员大小的整数倍;整个结构体的大小是最大基本数据类型的整数倍。

如何不定义结构体变量计算结构体成员的偏移量?

#define

struct Person {
char* name;
int age;
double weight;
};

int main(){
int dist1 = offset(struct Person, name);//0
int dist2 = offset(struct Person, age);//4
int dist3 = offset(struct Person, weight);//8
}

为什么要字节对齐?

C语言结构体内存对齐_c语言_13

C语言结构体内存对齐_c语言_14

printf("%d\n",  (char*)&(((struct Data*)0)->c) - (char*)&((struct Data*)0)->a)