2、C语言——“指针+偏移”方式访问结构体成员

发布时间:2026/5/27 10:07:23

2、C语言——“指针+偏移”方式访问结构体成员 C 语言指针历来是初学者的一大难点在实际工程开发中应用极广。本文以结构体成员访问为切入点系统讲解「指针 偏移」的底层原理与实战用法欢迎各位同行大佬批评指正。指针偏移规则「指针 数值偏移」 以「指针自身类型的大小」为单位跳转1.结构体成员为普通类型变量typedef struct { uint8_t a; // 偏移量 0 uint8_t b; // 偏移量 1 uint16_t c; // 偏移量 2 uint32_t d; // 偏移量 4 } structA; structA VarName; /* 上面的偏移量是以结构体第一个成员为基地址进行计算的(字节为单位)。 1、获取变量a的内容 *((uint8_t *)VarName 0) 2、获取变量b的内容 *((uint8_t *)VarName 1) 3、获取变量c的内容 *(uint16_t *)((uint8_t *)VarName 2) 4、获取变量d的内容 *(uint32_t *)((uint8_t *)VarName 4) */2.结构体成员里有结构体变量2.1 示例1typedef struct { uint32_t a1; // 偏移量 0 uint8_t b1; // 偏移量 4 uint8_t c1; // 偏移量 5 uint16_t d1; // 偏移量 6 } structA; typedef struct { structA sVar; // 偏移量 0 uint8_t a2; // 偏移量 8 uint8_t b2; // 偏移量 9 uint16_t c2; // 偏移量 10 uint32_t d2; // 偏移量 12 } structB; structB VarName; /* 1、获取变量a1的内容 *(uint32_t *)(((uint8_t *)VarName 0) 0) 2、获取变量b1的内容 *(uint8_t *)(((uint8_t *)VarName 0) 4) 3、获取变量c1的内容 *(uint8_t *)(((uint8_t *)VarName 0) 5) 4、获取变量d1的内容 *(uint16_t *)(((uint8_t *)VarName 0) 6) 5、获取变量a2的内容 *(uint8_t *)((uint8_t *)VarName 8) 6、获取变量b2的内容 *(uint8_t *)((uint8_t *)VarName 9) 7、获取变量c2的内容 *(uint16_t *)((uint8_t *)VarName 10) 8、获取变量d2的内容 *(uint32_t *)((uint8_t *)VarName 12) */2.2 示例2typedef struct { uint32_t a1; // 偏移量 0 uint8_t b1; // 偏移量 4 uint8_t c1; // 偏移量 5 uint16_t d1; // 偏移量 6 } structA; typedef struct { uint8_t a2; // 偏移量 0 uint8_t b2; // 偏移量 1 uint16_t c2; // 偏移量 2 structA sVar; // 偏移量 4 uint32_t d2; // 偏移量 12 } structB; structB VarName; /* 1、获取变量a1的内容 *(uint32_t *)(uint8_t *)(((uint8_t *)VarName 4) 0) 2、获取变量b1的内容 *(uint8_t *)(uint8_t *)(((uint8_t *)VarName 4) 4) 3、获取变量c1的内容 *(uint8_t *)(uint8_t *)(((uint8_t *)VarName 4) 5) 4、获取变量d1的内容 *(uint16_t *)(uint8_t *)(((uint8_t *)VarName 4) 6) 5、获取变量a2的内容 *(uint8_t *)((uint8_t *)VarName 0) 6、获取变量b2的内容 *(uint8_t *)((uint8_t *)VarName 1) 7、获取变量c2的内容 *(uint16_t *)((uint8_t *)VarName 2) 8、获取变量d2的内容 *(uint32_t *)((uint8_t *)VarName 12) */3.结构体数组3.1 示例1typedef struct { uint8_t a; // 偏移量 0 uint8_t b; // 偏移量 1 uint16_t c; // 偏移量 2 uint32_t d; // 偏移量 4 } structA; structA VarName[2]; /* VarName VarName[0] 1、获取变量VarName[0].a的内容 *(uint8_t *)((uint8_t *)VarName 0 * sizeof(structA) 0) 2、获取变量VarName[0].b的内容 *(uint8_t *)((uint8_t *)VarName 0 * sizeof(structA) 1) 3、获取变量VarName[0].c的内容 *(uint16_t *)((uint8_t *)VarName 0 * sizeof(structA) 2) 4、获取变量VarName[0].d的内容 *(uint32_t *)((uint8_t *)VarName 0 * sizeof(structA) 4) 5、获取变量VarName[1].a的内容 *(uint8_t *)((uint8_t *)VarName 1 * sizeof(structA) 0) 6、获取变量VarName[1].b的内容 *(uint8_t *)((uint8_t *)VarName 1 * sizeof(structA) 1) 7、获取变量VarName[1].c的内容 *(uint16_t *)((uint8_t *)VarName 1 * sizeof(structA) 2) 8、获取变量VarName[1].d的内容 *(uint32_t *)((uint8_t *)VarName 1 * sizeof(structA) 4) */3.2 示例2typedef struct { uint32_t a1; // 偏移量 0 uint8_t b1; // 偏移量 4 uint8_t c1; // 偏移量 5 uint16_t d1; // 偏移量 6 } structA; typedef struct { structA sVar; // 偏移量 0 uint8_t a2; // 偏移量 8 uint8_t b2; // 偏移量 9 uint16_t c2; // 偏移量 10 uint32_t d2; // 偏移量 12 } structB; structB VarName[2]; /* 1、获取变量VarName[0].a1的内容 *(uint32_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 0) 2、获取变量VarName[0].b1的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 4) 3、获取变量VarName[0].c1的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 5) 4、获取变量VarName[0].d1的内容 *(uint16_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 6) 5、获取变量VarName[0].a2的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 8) 6、获取变量VarName[0].b2的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 9) 7、获取变量VarName[0].c2的内容 *(uint16_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 10) 8、获取变量VarName[0].d2的内容 *(uint32_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 12) 9、获取变量VarName[1].a1的内容 *(uint32_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 0) 10、获取变量VarName[1].b1的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 4) 11、获取变量VarName[1].c1的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 5) 12、获取变量VarName[1].d1的内容 *(uint16_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 6) 13、获取变量VarName[1].a2的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 8) 14、获取变量VarName[1].b2的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 9) 15、获取变量VarName[1].c2的内容 *(uint16_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 10) 16、获取变量VarName[1].d2的内容 *(uint32_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 12) */3.3 示例3typedef struct { uint32_t a1; // 偏移量 0 uint8_t b1; // 偏移量 4 uint8_t c1; // 偏移量 5 uint16_t d1; // 偏移量 6 } structA; typedef struct { uint8_t a2; // 偏移量 0 uint8_t b2; // 偏移量 1 uint16_t c2; // 偏移量 2 structA sVar; // 偏移量 4 uint32_t d2; // 偏移量 12 } structB; structB VarName[2]; /* 1、获取变量VarName[0].a1的内容 *(uint32_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 0) 2、获取变量VarName[0].b1的内容 *(uint8_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 4) 3、获取变量VarName[0].c1的内容 *(uint8_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 5) 4、获取变量VarName[0].d1的内容 *(uint16_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 6) 5、获取变量VarName[0].a2的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 0) 6、获取变量VarName[0].b2的内容 *(uint8_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 1) 7、获取变量VarName[0].c2的内容 *(uint16_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 2) 8、获取变量VarName[0].d2的内容 *(uint32_t *)((uint8_t *)VarName 0 0 * sizeof(structB) 12) 9、获取变量VarName[1].a1的内容 *(uint32_t *)((uint8_t *)VarName 4 1 * sizeof(structB) 0) 10、获取变量VarName[1].b1的内容 *(uint8_t *)((uint8_t *)VarName 4 1 * sizeof(structB) 4) 11、获取变量VarName[1].c1的内容 *(uint8_t *)((uint8_t *)VarName 4 1 * sizeof(structB) 5) 12、获取变量VarName[1].d1的内容 *(uint16_t *)((uint8_t *)VarName 4 1 * sizeof(structB) 6) 13、获取变量VarName[1].a2的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 0) 14、获取变量VarName[1].b2的内容 *(uint8_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 1) 15、获取变量VarName[1].c2的内容 *(uint16_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 2) 16、获取变量VarName[1].d2的内容 *(uint32_t *)((uint8_t *)VarName 0 1 * sizeof(structB) 12) */3.4 示例4typedef struct { uint8_t a[2]; // 偏移量 0 uint8_t b[2]; // 偏移量 2 uint16_t c[2]; // 偏移量 4 uint32_t d; // 偏移量 8 } structA; structA VarName[2]; /* VarName VarName[0] 1、获取变量VarName[0].a[0]的内容 *(uint8_t *)((uint8_t *)VarName 0 * sizeof(structA) 0) 2、获取变量VarName[0].b[0]的内容 *(uint8_t *)((uint8_t *)VarName 0 * sizeof(structA) 2) 3、获取变量VarName[0].c[0]的内容 *(uint16_t *)((uint8_t *)VarName 0 * sizeof(structA) 4) 4、获取变量VarName[0].d的内容 *(uint32_t *)((uint8_t *)VarName 0 * sizeof(structA) 8) 5、获取变量VarName[1].a[0]的内容 *(uint8_t *)((uint8_t *)VarName 1 * sizeof(structA) 0) 6、获取变量VarName[1].b[0]的内容 *(uint8_t *)((uint8_t *)VarName 1 * sizeof(structA) 2) 7、获取变量VarName[1].c[0]的内容 *(uint16_t *)((uint8_t *)VarName 1 * sizeof(structA) 4) 8、获取变量VarName[1].d的内容 *(uint32_t *)((uint8_t *)VarName 1 * sizeof(structA) 8) */3.5 示例5typedef struct { uint32_t a1; // 偏移量 0 uint8_t b1[3]; // 偏移量 4 uint8_t c1; // 偏移量 7 uint16_t d1[2]; // 偏移量 8 } structA; typedef struct { uint8_t a2; // 偏移量 0 uint8_t b2; // 偏移量 1 uint16_t c2; // 偏移量 2 structA sVar[2]; // 偏移量 4 uint32_t d2; // 偏移量 28 } structB; structB VarName[2]; /* 1、获取变量VarName[0].sVar[0].a1的内容 *(uint32_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 0 * sizeof(structA) 0) 2、获取变量VarName[0].sVar[0].b1[1]的内容 *(uint8_t *)((uint8_t *)VarName 4 0 * sizeof(structB) 0 * sizeof(structA) 5) 3、获取变量VarName[1].sVar[1].b1[1]的内容 *(uint8_t *)((uint8_t *)VarName 4 1 * sizeof(structB) 1 * sizeof(structA) 5) */

相关新闻