Archive for April, 2006

有趣的C题

前两天在CSDN看到一篇帖子,帖子的内容是讨论SUN公司的一道笔试题

题目如下:

写一个带参数的宏get_struct_addr_from_member_addr(p, stru, m),
该宏能根据任意结构实体的某一个成员的地址,算出该结构实体的地址,
其中参数p是指向该成员的指针,stru是该结构体,m是该成员。

原帖地址:http://community.csdn.net/Expert/topic/4661/4661946.xml?temp=.5166437

本题的答案:
#define get_struct_addr_from_member_addr(p, stru, m) \
(stru*)( (char*)p – (char*)&(((stru*)0)->m) )

这个题目的最大困惑是((stru*)0)->m,乍一看,根不不知道是什么意思,估计没有一本C/C++语言的教材会提到这个用法。

根据帖子中september___29的回复,这个用法是依赖于编译器的实现的。((stru*)0)->m的意思是在内存地址为0的地方找到m的地址,实际上根本不可能在地址为0的地方找到m的地址,而令人惊奇的是,得到的结果却是struct stru的偏移量。

其根源是,编译器在进行((stru*)0)->m的运算时,要取得stru的偏移量才能取得m的地址,在m不存在时,偏移量就不会改变,于是结果就得到了stru的偏移量。

Comments (1)