宏定义求结构体某个变量相对其偏移量的问题

程序员面试宝典的问题之一,做的时候觉得有些小问题不懂,就搜了一下,整理整理,再加一点自己的理解。

题目:

用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量

如:struct student 

int a; 
char b; 
double c; 

则: 
FIND(student,a); //等于0 
FIND(student,b);//等于4

答案:#define FIND( struc, e ) (size_t)&(((struc*)0)- >e)

首先,ANSI C标准允许任何值为0的常量被强制转换成任何一种类型的指针,并且转换结果是一个NULL指针,所以我们的第一步(struc*)0,就是把0转换为一个struc类型的指针。利用这个访问结构体里面元素的话,是非法的。参考文献:http://blog.csdn.net/huichengongzi/article/details/7478739 里面提到:“&(((s*)0)->m)的意图并非想存取s字段内容,而仅仅是计算当结构体实例的首址为((s*)0)时m字段的地址。聪明的编译器根本就不生成访问m的代码,而仅仅是根据s的内存布局和结构体实例首址在编译期计算这个(常 量)地址,这样就完全避免了通过NULL指针访问内存的问题。”

参考文献:http://www.cnblogs.com/alexqdh/archive/2011/04/30/2029447.html 里面提到,如果不加(size_t)则输出的是十六进制

这样对访问第一个元素是没问题的,但是如果访问元素b,或者元素c时,编译器会报错,原因可能是我们通过NULL指针访问了结构体中的元素(具体没搞明白,汇编那块学的不太好)。

所以我觉得(size_t)这个强制类型转换是必须加的,要不然编译器会认为你在利用NULL指针访问结构体。

具体代码:

 

#include <iostream>

using namespace std;

struct student{
	int a;
	char b;
	double c;
};

#define findoffset(stru,e) ((size_t)&((stru*)0)->e)
//#define findoffset(stru,e) (&((stru*)0)->e)

int main()
{

	cout<<findoffset(student,a)<<endl;
	cout<<findoffset(student,b)<<endl;
	cout<<"ans is:"<<endl;
	//测试null指针是否能够访问结构体第二个元素
	//	cout<<&(((student*)0)->b)<<endl;
	student *p,stu;
	stu.a = 10;
	stu.b = 'e';
	stu.c = 1.0;
	p = &stu;
	cout<<&(p->a)<<endl;
	//cout<<findoffset(stu,a)<<endl;
	//cout<<findoffset(stu,b)<<endl;
	return 0;
}



本人比较爱乱想,因此加了一个看看是否能通过结构体实例进行偏移量计算,结果是不可以,具体原因请将定义的宏带入就可以知道,实例名并不是类型,所以编译器在进行指针转换的时候会不知所措,而报错。。

 

总结一下:

1、(type*)0,将0转换为type类型指针,且其不能访问结构体内部数据,只能将地址转换为十进制数输出。

2、结构体实例不能作为所定义的宏里面的变量来计算对应的偏移量。

 

个人浅见,不一定正确。微笑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值