❤️offsetof计算偏移量的宏❤️
本文主要对offsetof的原理进行分析具体的原理具体定义则会参照库中的宏定义。
1.😏具体使用和参数的分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjp0JLaM-1674715441651)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230126134048451.png)]
函数作用分析:
计算结构体中,成员存放位置在结构体中相对结构体起始位置的偏移量。
返回值和参数分析:
structName
结构体的名字;
memberName
所要计算的结构体成员的名字;
返回值是size_t类型是重定义的无符号整型,可以用int型接收。
2.🫥源码定义和使用示例
源码
#define offsetof(s,m) ((size_t)&(((s*)0)->m))//宏的定义不能加分号
具体使用
struct S
{
char a;
int b;
char c;
};
#define OFFSET(str_name,stat_name) (size_t)&((( str_name *)0)->stat_name)//模仿库中实现的定义的宏
//不能用int类型来进行转换,因为这样会发生截断精度丢失等问题,编译器会发生错误不能通过
int main() {
printf("偏移量为=>%d\n", OFFSET(struct S, a));
printf("偏移量为=>%d\n", OFFSET(struct S, b));
printf("偏移量为=>%d\n", OFFSET(struct S, c));
return 0;
}
结果:
3.原理解析
传入结构体的名字和成员名的时候,会对宏中对应参数进行替换,就会得到如下代码:
(int)&(((struct S *)0)->a)
如果想要读懂这个,那我们就要从内部一点一点的分析。其中的(struct S *)0 是对0进行强制转换成结构体指针类型,就相当于把结构体提取出来从零地址重新摆放,来计算偏移量,变量摆到哪就是偏移多少。
图解
是对0进行强制转换成结构体指针类型,就相当于把结构体提取出来从零地址重新摆放,来计算偏移量,变量摆到哪就是偏移多少。
图解