结构体的大小:
规则1:结构体的大小等于结构体内最大类型的整数倍
规则2:结构体内的成员的首地址相当于结构体首地址的偏移量是其类型大小的整数倍
规则3:为了满足规则1和2在结构体成员之后进行字节填充
结构体位域的大小规则:
共用体:
为了提速之类的,在结构体和联合体的内存块中,是按照一定的规则安排的
联合体:
联合体的内存不会为了所有成员安排,而是只取最大的成员的所需内存大小,每次只能使用其中一个成员。但是有一个问题:
typedef union
{
char a;
int[5] b;
double c;
}
当然只取最大的int数组的大小20没错,但是double是8字节的,而此时联合体已经按int的4字节对齐了,所以还要额外多加4字节的内存来保证8的倍数。所以最后结果是24
所以联合体的内存除了取最大成员内存外,还要保证是所有成员类型size的最小公倍数
共用体大小:共用最宽的数据类型的空间大小
重点:无论是共用体还是结构体,都是最宽类型的整数倍
每个成员类型存储起始位置都是按类型整数倍开始储存的
如果共同体在结构体里面时 结构体里面含有共用体,共用体在结构体里面的类型是它最大宽度的类型
例子:
#include<iostream>
typedef union
{
char a;
int b[4];
double c;
} my;
struct test
{
int i;//4个字节
my cow;//以为double类型,所以以8开始,占16个字节 //所以前两个变量是24个字节
char a;//1
short int c;//2
}myaa;
必须是double 的整数倍 ,所以32
int main()
{
std::cout<<sizeof(myaa);
return 0;
}
所以:输出为32,//共用体字节数>=成员变量的内存,他是以最宽类型整数倍来开辟内存的。
所以在结构体内,是共用体(16个字节)以double类型存在的。
最后一点:
#include <stdio.h>
struct GPIOF{
unsigned int d:4;
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
unsigned int res:25;
};
int main(){
struct GPIOF led = {0, 1, 0, 1, 0};
printf("%d %x\n", led, led.a);
led.a = 0;
printf("%x %d\n", led, led.a);
return 0;
}
在嵌入式中最好设它为无符号整型。
当设它为有符号整数时:
struct GPIOF{
int d:4;
int a:1;
int b:1;
int c:1;
int res:25;
};
输出结构等于 80 ffffffff(十六进制)
40 0
因为赋值时,比如led.a=1;
剩下位补1 因为为有符号int(其实等于-1)
还不知道为什么,如果要取正确的位数就要&结构体成员的位数
所以尽量用unsigned.