使用宏定义来获取一个结构体成员相对于该结构体首地址的偏移量


目的:获取一个结构体成员相对于该结构首地址的偏移量


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 ; 

目的:便于不同系统之间的移植

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页