若有结构体
struct node{
int m1;
char m2;
short m3;
};
定义宏,获得结构体内各成员的偏移,比如m1的偏移是0,m2的偏移是4,m3的偏移是6
#define off(n) ((unsigned long)(&((struct node *)0)->n))
这样可以调用off(m1),off(m2),0ff(m3)分别获得结构体的三个成员的偏移。
还可以做的通用一点:
#define off(st,n) ((unsigned long)(&((struct st *)0)->n))
这样可以调用off(node,m1),off(node,m2),0ff(node,m3)分别获得node结构体的三个成员的偏移,
如果还有一个结构体list,有成员变量a,那么同样可以使用off(list,a)来获得它的偏移。
还可以再改一点:
#define off(st,n) ((unsigned long)(&((struct st *)0)->m##n))
那么现在可以通过off(node,1),off(node,2),off(node,3)分别获得node结构体的三个成员的偏移.
注:宏定义里有个(struct node *)0,好像是0指针,访问0地址岂不是非法? 其实不是,off(st,n)的值在编译期间就已经算出来了,编译完后,它已经是一个整数值,就不存在0地址问题了。
类似这种问题还有 sizeof(a++),其实a的值并不会改变,因为编译完后,sizeof(a++)已经被一个整数值取代了。
这个宏定义在C标准库的头文件 stddef.h 里有定义
typedef unsigned long size_t;
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
阅读(3083) | 评论(0) | 转发(0) |