P-结构体成员的偏移量---宏定义实现

来源:互联网 发布:数据库中删除重复数据 编辑:程序博客网 时间:2024/04/19 21:03

最近在找实习,前天接到Tencent的电话面试,有点小激动,一点准备都没有,站在实验室外楼梯边的窗户旁就这么开始了,一开始自我介绍,然后主要问了一下项目情况,后来就是基本的常识性的编程知识,最后问了一道算法题,在面试官的提醒下,最后基本都算答出来了,但有一题,尼玛我实在想不出来,也就没答出来,问题是:怎样求结构体成员的偏移量

我的第一反应是:定义结构体成员,然后取地址,求差值,然后面试官来了一句:不许实例化,定义一个宏来实现。尼玛,我当时就懵了,不实例化,让我怎么搞。。。然后我苦思冥想了几分钟,然后说这个我真不知道。。。面试官说那咱就换个问题吧。。。生气

今天把那天面试问的问题整理了一下,尼玛我居然发现这个问题在《程序员面试宝典》P45,原题。。。,先把结果贴出来:

#define STRUCT_MEMBER_OFFSET(StructType, memberName) (size_t)&(((StructType *)0)->memberName) 
首先看到这个结构我的第一反应就是:我次奥。。。,空指针怎么可以访问结构体的成员,为什么,空指针是不能访问任何成员的。

看到网上千篇一律的说:如果通过(StructType *)0访问该结构体的成员肯定是非法的,而(size_t)&(((StructType *)0)->memberName)的实际意图并非想取memberName字段的内容,而是计算当前结构体首地址为(StructType *)0时,memberName字段的地址。

但是我想说的是根据这个表达式的写法:由操作符的优先级可以知道程序会计算括号内部的表达式然后再取地址。

网上又说:聪明的编译器根本就不生成访问memberName的代码,而仅仅是根据结构体的内存布局和结构体首址在编译期间计算这个地址,这样就完全避免了通过NULL指针访问内存的问题。

&(((StructType *)0)->memberName);//success(((StructType *)0)->memberName);//error
上面两个表达式一个是正确的一个是错误的,难道编译器会特意区分NULL指针访问结构成员时前面有没有取地址符号吗。。。

希望有人能解释一下,多谢了。

Mar 30, 2013 @lab

原创粉丝点击