1. 结构体的存储
- 结构体各个成员的地址是连续的
- 结构体变量的地址是第一个成员的地址
2. 64位操作系统8字节对齐
- 结构体的总字节大小是各个成员字节的总和,字节的总和需要是最宽成员的倍数
- 结构体的首地址是最宽成员的倍数
- 结构体各个成员的偏移量是该成员字节的倍数,否则填充空字节
例子1:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct A
{
int a; //4
char b; //1
short c; //2
float d; //4
}a;
int main(int argc, const char *argv[])
{
printf("a=%p\n", &a);
printf("a.a=%p\n", &a.a);
printf("a.b=%p\n", &a.b);
printf("a.c=%p\n", &a.c);
printf("a.d=%p\n", &a.d);
printf("sizieof(a)=%ld\n", sizeof(a));
return 0;
}
计算
运行结果
a=0x55b0037eb018
a.a=0x55b0037eb018
a.b=0x55b0037eb01c
a.c=0x55b0037eb01e
a.d=0x55b0037eb020
sizieof(a)=12
例子2:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct A
{
int *a; //8
char b; //1
double c; //8
long d; //8
} s1;
int main(int argc, const char *argv[])
{
printf("s1=%p\n", &s1);
printf("s1.a=%p\n", &s1.a);
printf("s1.b=%p\n", &s1.b);
printf("s1.c=%p\n", &s1.c);
printf("s1.d=%p\n", &s1.d);
printf("sizieof(s1)=%ld\n", sizeof(s1));
return 0;
}
计算
运行结果
s1=0x55e754e4e040
s1.a=0x55e754e4e040
s1.b=0x55e754e4e048
s1.c=0x55e754e4e050
s1.d=0x55e754e4e058
sizieof(s1)=32
例子3:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct S
{
char a[5]; //
int b; //
} s3;
int main(int argc, const char *argv[])
{
printf("s3=%p\n", &s3);
printf("s3.a=%p\n", &s3.a);
printf("s3.b=%p\n", &s3.b);
printf("sizieof(s3)=%ld\n", sizeof(s3));
return 0;
}
计算
运行结果
s3=0x55da08b43018
s3.a=0x55da08b43018
s3.b=0x55da08b43020
sizieof(s3)=12
3. 32位操作系统,4字节对齐:
- 结构体的总字节大小是各个成员字节的总和,字节的总和需要是最宽成员的倍数
- 如果最宽成员是1,则是1的倍数
- 如果最宽成员是2,则是2的倍数
- 如果最宽成员是4,8,则是4的倍数
- 结构体的首地址是最宽成员的倍数
- 结构体各个成员的偏移量是该成员字节的倍数,否则填充空字节
- 如果成员字节是1,则偏移量是1的倍数
- 如果成员字节是2,则偏移量是2的倍数
- 如果成员字节是4,8,则偏移量是4的倍数
例子4:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct S5
{
char a; //
int *b;
double c;
long d;
}s5 ;
struct S6
{
char e[5];
struct S5 s5;
int f;
}s6;
int main(int argc, const char *argv[])
{
printf("s6.e=%p\n", &s6.e);
printf("s6.s5.a=%p\n", &s6.s5.a);
printf("s6.s5.b=%p\n", &s6.s5.b);
printf("s6.s5.c=%p\n", &s6.s5.c);
printf("s6.s5.d=%p\n", &s6.s5.d);
printf("s6.f=%p\n", &s6.f);
printf("sizieof(s6)=%ld\n", sizeof(s6));
return 0;
}
~
计算
运行结果
s6.e=0x565cf040
s6.s5.a=0x565cf048
s6.s5.b=0x565cf04c
s6.s5.c=0x565cf050
s6.s5.d=0x565cf058
s6.f=0x565cf05c
sizieof(s6)=32