#include#define ADDR 100 //地址常量 //#define FIND(struc,e) ((unsigned int)(&((struc*)ADDR)->e) - (unsigned int)(struc*)ADDR) #define FIND(struc,e) (unsigned int)(&((struc*)0)->e) struct stu{ char a[20]; int b; double c; }; int main() { // 下面注释掉的这一段是不适用宏定义而直接取偏移量的方法。 // ANSI C标准允许任何值为0(严格意义上任何常数)强制转化 // 为任何一种类型的指针,并且转换结果就是一个NULL指针. // 因此,(struc*)0就一个NULL指针,一个(struc*)类型指针 /* struct stu *qstu = NULL; //理解形式 printf("%d\n",(unsigned int)&(qstu->a) - (unsigned int)qstu); printf("%d\n",(unsigned int)&(qstu->b) - (unsigned int)qstu); printf("%d\n",(unsigned int)&(qstu->c) - (unsigned int)qstu); //简化形式 printf("%d\n",(unsigned int)&(qstu->a)); printf("%d\n",(unsigned int)&(qstu->b)); printf("%d\n",(unsigned int)&(qstu-> c)); */ printf("%d\n",FIND(stu,a)); printf("%d\n",FIND(stu,b)); printf("%d\n",FIND(stu,c)); return 0; } /* (struct*)0 表示将常量0强制转化为struc*型指针所指向的地址 &(((struct*)0)->e) 表示取结构体指针(struc*)0的成员e的地址 因为该结构体的首地址为0,那么偏移量就是 (成员e的地址)-(结构体的首地址)= (成员e的地址)- 0 =(成员e的地址) 当然这样写也是可以的。 #define FIND(struc,e) ((unsigned int)(&((struc*)0)->e) - (unsigned int)(struc*)0) 注意这里的0只是一个常量而已,唯一的目的就是为了方便运算。 详细的形式如下 #define ADDR 100 #define FIND(struc,e) ((unsigned int)(&((struc*)ADDR)->e) - (unsigned int)(struc*)ADDR) (unsigned int)(&((struc*)ADDR)->e) 元素e的地址 (unsigned int)(struc*)ADDR 结构体首地址 二者做差得到偏移地址 那么如果ADDR取0的话 就可以简化为如下形式 #define FIND(struc,e) (unsigned int)(&((struc*)0)->e) */