基于VC++ 6.0下的offsetof(TYPE, MEMBER)个人实验心得

     最近在学习linux下的内核链表,发现linux的内核链表不同于传统的链表,于是打算把这套内核链表移植出来,方便以后使用,不过在移植offsetof(TYPE, MEMBER)这个宏的时候遇到了很多之前不懂的问题,经过几天的努力终于把offsetof这个宏弄的明明白白了。

     正确源代码:

 1 #include "stdafx.h"
 2 
 3 
 4 #define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
 5 
 6 typedef struct _test
 7 {
 8       char i;      
 9       double k;
10       int  j;
11 }Test;
12 
13 
14 int main(int argc, char* argv[])
15 {   
16     Test a;
17     a.i = 1;
18     a.j = 2;
19     a.k = 3;
20     int  *p = &(a.j);
21     printf("j元素的偏移量:%p\n", offsetof(Test, j));              //打印j元素在相对于Test结构的地址偏移量
22     printf("j元素的地址:%p\n", p);                              //打印j元素的地址
23     printf("j地址减去偏移量之后的地址:%p\n", (char *)p - offsetof(Test, j));  //打印j地址减去偏移量之后的地址值
24     printf("Test结构a的地址:%p\n", &a);                             //打印Test结构a的地址值,若j地址减去偏移量 = a地址值,则offsetof正确
25     printf("Test结构的大小:%d\n", sizeof(struct _test));           //打印Test结构的大小
26     return 0;
27 }

 

     遇到的问题:

1. 在offsetof宏中为什么要用(size_t)强制转换?

 

 

           由上图可得答案。

2. 为什么在 printf("j地址减去偏移量之后的地址:%p\n", (char *)p - offsetof(Test, j)); 这句要在p前面加上强制转换(char *)?

  假设两种情况:

  1、不加强制转换

  实验结果:

  

   有实验结果可以看到:实验结果的3,4行的地址不相等,则说明实验结果错误;

  2、加强制转换

  实验结果:

  

  可以看到,实验结果正确。

  那么为什么要加强制转换,实验结果才正确呢?

  原因:因为p是一个指针,指针减去一个数,等于指针的值减去指针类型的倍数,例如,int *p=&a;

                                                                                                              p = p - 1;

                                                                                                              那么相当于p的值减去了4(因为int 型指针大小为4个字节)

 

  以上为我个人见解,不一定正确,但可以参考。

posted @ 2015-03-22 11:36  Fight_for_a_sweet  阅读(607)  评论(0编辑  收藏  举报