为了弄清楚这几种结构体的作用以及所占内存大小,结合实例分析一下,理清一下自己的思路。
RegTypedef *content;
uint16_t size = 0;
content = (RegTypedef*)&PROTOCOL_Info->Data[size];
首先弄清楚 RegTypedef 所占内存大小。
typedef struct
{
enum
{
A = 0x01,
B,
C,
D,
E,
F,
G = 255,
H,
I = 312,
} Type;
union
{
uint8_t Q[20];
uint8_t W[10];
uint8_t E1[10];
uint8_t R[2];
uint8_t T[10];
uint8_t Y[10];
uint8_t U;
uint8_t O[15];
uint8_t P[20];
} RegBody;
} RegTypedef;
它是一个枚举+联合构成的结构体。
一、枚举
enum结构类型中的变量个数,最大能够定义2^32个,编译器一般根据enum结构类型中定义的变量的值分配enum类型大小。
A=0x01,后面没特别标注变量,数值依次递增,若整个结构体只到G这个变量,这个枚举结构体则只占用1个字节,因为所有数值小于2^8=256,1个字节就能表示。其中H=256。但是这个结构体实际是一直到I=312。大于2^8=256,小于2^16=512,所以该结构体占用内存2个字节,2byte=16bit。
二、联合
联合体中的成员共用一块空间,联合的大小至少是最大成员的大小。当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
RegBody这个联合体的每个成员都是字符型,占1个字节,则它的最大对齐数是1个字节。其中占用内存最大的数组,占用了20个字节,20个字节是最大对齐数1个字节的20倍,满足要求。所以该结构体占用的内存大小事20个字节。
综上所述,RegTypedef 所占内存大小22个字节。
其次我们要搞清楚PROTOCOL_Info这个结构体的大小
PROTOCOL_MsgBufferTypedefPROTOCOL_Info;
typedef enum
{
A = 0x01,
S,
D,
F,
G,
H,
J,
K,
K = 0x18,
} PROTOCOL_InfoTypeEnum;//最大0x18没超过256,该结构体占1个字节
typedef struct
{
FunctionalState Registed; //stm32底层定义的状态位,类型是enum,也是占1个字节
PROTOCOL_InfoTypeEnum SendMsgType; //该结构体占1个字节
PROTOCOL_MsgBufferTypedef Msg; //该结构体占154个字节
uint16_t M;
uint8_t N;
uint16_t B;
uint16_t V;
uint8_t C;
FunctionalState X;
uint32_t *Z;
enum
{
PROTOCOL_OTA_STATUS_INVALID,
PROTOCOL_OTA_STATUS_ENABLE,
PROTOCOL_OTA_STATUS_LOAD,
} OtaStatus; //该结构体占1个字节
} PROTOCOL_InfoTypedef;
typedef struct
{
uint8_t A;
uint8_t S[2];
uint8_t D[2];
uint8_t F;
uint8_t G[16];
PROTOCOL_InfoTypeEnum H;
uint8_t Data[128];
uint8_t J[2];
uint8_t K;
} PROTOCOL_MsgBufferTypedef;//1+2+2+1+16+1+128+2+1=154个字节
综上该结构体占用1+1+154+2+1+2+2+1+1+4+1= 170个字节。
最后分析一下content = (RegTypedef*)&PROTOCOL_Info->Data[size];的作用
目的是为了将PROTOCOL_Info->Data[size]的首地址赋给content,但是两者类型不同。所以将PROTOCOL_Info->Data[size]的首地址 强制转换为 RegTypedef型指针,即该指针指向PROTOCOL_Info->Data[size]的首地址,并把该地址赋给content。
我也比较小白,基础比较差,有错请大佬温和指出