offsetof

offsetof16.offsetof宏#defineoffsetof(TYPE,MEMBER)((int)&((TYPE*)0)->MEMBER)上式是offsetof的定义式,其中TYPE是结构体变量类型,MEMBER是结构体中的成员,返回的是该成员的地址相对结构体首地址的偏移量。offsetof宏的原理:我们虚拟一个type类型结构体变量,然后用type.member的方式来访问哪个m

16.offsetof宏

#define offsetof(TYPE,MEMBER)
((int) &((TYPE *)0)-> MEMBER)

上式是offsetof的定义式,其中TYPE是结构体变量类型,MEMBER是结构体中的成员,返回的是该成员的地址相对结构体首地址的偏移量。

offsetof宏的原理:我们虚拟一个type类型结构体变量,然后用type.member的方式来访问哪个member元素,继而得到member相对整个变量首地址的偏移量。

解析((int) &((TYPE *)0)-> MEMBER):

(TYPE *)0:将地址0强制类型转化为指向TYPE类型的指针,可以记为p = (TYPE *)0;p是指向TYPE类型的指针,它的值为0;

((TYPE *)0)-> MEMBER:->的优先级高一些,将该指针指向结构体中的MEMBER成员;

&((TYPE *)0)-> MEMBER):对该成员取地址;该值即为MEMBER成员的偏移量,因为该结构体类型的首地址为0.

((int) &((TYPE *)0)-> MEMBER):将该地址转换成int,

offsetof中的亮点就是将该结构体的首地址强制为0.

struct mystruct

{


char a;


int b;


short c;


};

#define offsetof(TYPE,MEMBER)
((int) &((TYPE *)0)-> MEMBER)

int main(void)

{


int offseta = (int)offsetof(struct mystruct, a);


printf("offseta = %d.\n", offseta);


int offsetb = (int)offsetof(struct mystruct, b);


printf("offseta = %d.\n", offsetb);


int offsetc = (int)offsetof(struct mystruct, c);


printf("offsetc = %d.\n", offsetc);

}

/****************************************************************/

当然,在我们定义简单的结构体变量的时候,我们是可以直接通过转换来计算偏移量的,方法如下:

struct mystruct

{


char a;
// 0


int b;
// 4


short c;
// 8

};

int main(void)

{


printf("整个结构体变量的首地址:%p.\n", &s1);
//&s1取结构体首地址


printf("s1.b的首地址:%p.\n", &(s1.b));
//&(s1.b)取b成员地址


printf("偏移量是:%d.\n", (char *)&(s1.b) - (char *)&s1);
//b对整个结构体的偏移量

}

/****************************************************************/

我们也可以先让一个指针指向该结构体的首地址,然后将该指针移动适当的偏移量,然后解引用移动后的指针来获取对应成员的值。

struct mystruct

{


char a;
// 0


int b;
// 4


short c;
// 8

};

int main(void)

{


struct mystruct s1;


s1.b = 12;





int *p = (int *)((char *)&s1 + 4);
//&s1,结构体的首地址,(char *)&s1转为字符形式指针,然后指针走4个偏移


printf("*p = %d.\n", *p);

}

本文来源一吱乖怂鼠,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/209971
0

发表评论