LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1061|回复: 7

请问一个宏定义

[复制链接]
发表于 2006-10-24 18:26:17 | 显示全部楼层 |阅读模式
这个宏定义是这样的:
#define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)

其中wpa_ssid是一个结构(这不用说),传递参数v是这个结构中的一员,大致意思我猜可能是得到这个成员的偏移地址,只是我不明白这样做为什么正确,为什么要使用这样的定义以及这样做有什么好处?
请指教。
发表于 2006-10-25 10:21:47 | 显示全部楼层
你的猜测不错,确实是返回结构成员v相对结构起始地址的偏移量。

至于为什么正确,这还是问问C语言吧。

好处之一,就是代码与结构的具体内容没有关系。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-25 12:25:51 | 显示全部楼层
谢谢duangw,还是想从原理上理解它,哪儿能找到更多的资料呢?
回复 支持 反对

使用道具 举报

发表于 2006-10-25 15:22:34 | 显示全部楼层
呵呵,可能是这样的,大家说说看对不对
先定义一个类型为struct wpa_ssid *的0变量,然后用这个0变量取它的成员v,最后用一个&符号取地址,最后再用类型转换把取出的地址转换为(void *)的类型.
昨天把&符号当成"与"了,想啊想啊想,想不通,呵呵, 当成取地址就比较好理解了.
回复 支持 反对

使用道具 举报

发表于 2006-10-25 16:58:50 | 显示全部楼层
获取成员V在这个结构中的偏移.
因为是从0开始,所以它返回的也就是这个成员在结构中的位置啊
void *p = NULL
struct _a
{
   ...
  void *v;
  ...
}a;


p = OFFSET(v) + &a;
这个p就指向结构a中的成员v了.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-25 17:09:25 | 显示全部楼层
感觉还是有些别扭,关键是 (struct wpa_ssid *) 0,想一下(int *)0这是一个什么东东?"0变量“怎么指向它的成员?,0和NULL?
回复 支持 反对

使用道具 举报

发表于 2006-10-25 22:12:06 | 显示全部楼层
结构的成员的地址说白了就是在结构的地址上再加一个偏移。
假如有一个 struct a,包含一个成员 x,那么 x 的偏移地址就是
&(a.x) - &a
但是这有两点坏处,第一,必须有一个实例,第二,要做一次减法运算
为了解决问题,我们可以通过指针的灵活特性来实现。假设 a 的地址为 0,
那么上式就化简为
&(a.x) - &a = &((*0).x) - &(*0) = &((*0).x)
由于没有对假想的 a 与 a.x 做读写,因此也不会导致错误
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-10-26 08:39:59 | 显示全部楼层
总算明白了,谢谢大家
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表