结构体内存,大小,联合,位域
C语言中结构体内存分配(内含数组与结构体版)----超级详细版_Abyssal丶Sun的博客-CSDN博客_c语言结构体内存分配参考
结构体地址内存是自增的,
我们所知一个地址的内存能存储1字节
struct student { uint8_t name; uint8_t a; uint8_t b; }; struct student stu; printf("%d\r\n",sizeof(stu)) printf("%d,%d,%d",&stu.name,&stu.a,&stu.b);
结构体大小 //这个结构体最长的基本单位是8位,为1字节 name为结构体首地址没有偏移,内存大小为1字节,是1字节的整数倍; a也是1字节, b也是1字节 所以是1+1+1 = 3字节
结构体地址
//以上的结果就是b的地址比a的地址大1,a比name的地址大1 当把上面的uint8_t替换成uint16_t的类型是,输出的结果就会是 b比a大2,a比name大2; 原因是一个内存存放的是8位数据,uint16_t是16位,所以地址加1内存不够所以地址加2
struct student { char a[3]; char b[20]; char c; double d; char e; } 求长度 sizeof(struct student) //此结构体最长的基本单位是double,为8字节 a是数组,char为1字节,首地址没有偏移,a内存为3 数组b的字节数为20,与前面相加为20+3 = 23不是8的倍数所以空出一个字节+1所以到b处总共是24字节 但是char c为1字节刚好能填补b处空出的一个字节,由于c补充过去,所以到char c总共是24字节,尽管c的1字节补充过去只是数据对齐,地址依旧在b【20】的地址上+1 double d 为8字节8的整数倍, char e为1字节不是8的整数倍,补充到8的最小整数倍,所以char e 的所占字节为8. 所以总字节为24+8+8 = 40个字节
例2struct student { char a[3]; char b[20]; int c; double d; char e; } 求长度 sizeof(struct student) 最大毕本单位double 8字节
a是数组,char为1字节,首地址没有偏移,a内存为3 数组b的字节数为20,与前面相加为20+3 = 23不是8的倍数所以空出一个字节+1所以到b处总共是24字节
int c为4字节,b处空下的一字节不够4字节填充所以在申请4字节,但是由于4字节不是8的整数倍,所以空出4字节为8字节
double d 8>4填充不了,所以为8字节
char e 1字节不够8字节,补充8字节
所以总数为8+24+8+8 = 48
联合体(共用体)大小计算
union abc
{
char a;//1字节
int b;//4字节
}
所以结构体大小为4字节
联合体成员共用一块空间,所以内存空间至少为最大成员大小
union abc
{
char a[5];//对齐数为 为1,占用5字节
int b;//对齐数为4,占用4字节
}
对齐数4>1,4是最大对齐数,5不是4的倍数,空掉3个byte所以大小为8字节
联合体大小是最大对齐数的整数倍
位域 //位域&地址报错
#include<stdio.h>
struct A
{
//一开始会创建一个int类型的存储空间,4byte = 32bit
//_a会用掉2个bit
int _a : 2;//_a成员占2个bit位
//_b会用掉5个bit
int _b : 5;//_b成员占5个bit位
//_c会用掉10bit
int _c : 10;//_c成员占10个bit位
//_d需要30个bit,但上面只剩下15个bit,所以会再创建4byte的空间
int _d : 30;//_d成员占30个bit位
//所以总共大小是8byte
};
int main()
{
printf("%d\n", sizeof(struct A));
return 0;
}