C代码如下:
#include <stdio.h>
#define GET_OFFSET(data,member) (size_t)(&(((typeof(data)*)0)->member))
typedef struct student{
int a;
char ch[2];
double d;
}student_t;
int main(int argc, char const *argv[])
{
student_t stu ;
int offset ;
offset= GET_OFFSET(stu,d);
printf("%d\n",offset );
return 0;
}
代码分析如下:
1. typeof 关键字:
用于获取修饰修饰变量的数据类型。比如 int value; typeof( value ) 的作用是获得 value 的数据类型int 。
用法:
int value; 我想要定义一个 和value这个变量类型一样的新变量new_value ;
操作像这样: typeof(value) new_value ;
该用法可以用在函数的值传递中,在不知道值的类型的时候,可以定义和它类型相同的新变量。
2. typedef :
为数据类型起一个名字 :比如 typedef struct student student_t ;
约定 :一般新名字后面以 _t 结尾,表示是一个构造出来的新类型名字,便于理解。
student_t stud1 ; 等价于 struct student stud1 ; 很显然 前者更有利于移植和阅读。
3. ((data_type *)0) :
作用:把数字 0 强制转换成 (data_type) 类型的指针。
比如:( struct student * )0 的作用是把 0 转换成 struct student类型的指针,用于引用struct student数据类型类型的成员。
在这个题目中: ((typeof(data)*)0)->member 的目的是 把 0 转成 data 变量对应的数据类型的指针,然后通过该指针引用该类型的成员的值。
对于本题而言: (size_t)(&(((struct student *)0)->d)) : & 用以获取struct student结构的成员d ,然后,获得d 的地址,将它转成 size_t 的数据类型量。
其中 size_t 的定义是 typedef unsigned int size_t ;
(size_t)(&(((struct student *)0)->d)) 它的值是变量d的地址,为什么是偏移值呢? 因为 起始地址我们认为规定为 0。
4. size_t :
typedef unsigned int size_t ;
1
目的:便于不同系统之间的移植