思路:根据结构体部分成员的值,求出该结构体的首地址,从而求出所有成员的值。
下面是一个结构体的内存模型
低地址 ——> 高地址
|_________|______|______|_____________|
首地址 成员1 成员2 成员3 …… 末地址
根据内存模型,思考:如果可以求出某个成员的地址,再求出该成员离首地址的偏移量,然后用地址减去偏移量就可以求出首地址。
以成员2为例:
低地址 ——> 高地址
|_________|______|______|_____________|
首地址 成员1 成员2 成员3 …… 末地址
|_______n_______|
hp mp2
hp代表结构体首地址;n为成员2到首地址的偏移量,即灰色线段的长度;mp2为成员2的地址。故,hp = mp2 – n。
有了这些基础,再看看本文讨论的题目“根据结构体某个成员的地址求出结构体所有成员的值”,那么mp2的值相当于是已知的。
那么剩下的问题就是如何求n,也就是如何求出mp2到结构体首地址的偏移量。
首先,定义一个结构体:
typedef struct _tagTest
{
int x;
int y;
int z;
}Test,t;
假设我们知道&t.y。
那么,(size_t)&((Test*)0->y)的含义就是:将0强转成“Test*”类型的指针,求出y的地址。这个y的地址就是相对于地址0的绝对长度,也就相当于它在所在结构体中的偏移量。
示例代码:
#include <stdio.h> #define offsetof(type, mumber) ((int)(&((type *)0)->mumber)) #define getheadpoint(address, type, field) \ ((type *)((char *)(address)-(unsigned long)(&((type *)0)->field)))
typedef struct _test_ { int x; int y; int z; }Test;
int main(void) { Test *p; Test tmp; tmp.x = 1; tmp.y = 2; tmp.z = 3; printf("offset = %d\n",offsetof(Test,z)); p =getheadpoint(&tmp.z,Test,z); printf("x = %d\ny = %d\nz = %d\n",p->x,p->y,p->z); return 0; }
|