zoukankan      html  css  js  c++  java
  • 利用宏来求出结构体成员的一些信息

    1 #define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )

    宏功能:获得一个结构体变量成员在此结构体中的偏移量。

    1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
    2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;

    3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址,即相对于0的偏移量,要的就这个;
    4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型,size_t应该最终为unsigned int类型。
    此宏的巧妙之处在于将 0 转换成(TYPE*),这样结构体中成员的地址即为在此结构体中的偏移量。

    示例:

    #include <stdio.h>

    #define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER))

    struct _test_
    {
    int x;
    int y;
    float z;
    };

    int main(void)
    {
    int temp = -1;
    temp = offsetof(struct _test_, z);
    printf("temp = %d\n", temp);
    return 0;
    }

    运行后结构为:temp = 8

    显然求出了 结构体成员变量 z 在结构体中的偏移量为 8
    #define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})

    宏功能:从结构体(type)某成员变量(member)指针(ptr)来求出该结构体(type)的首指针。

    #include <stdio.h>

    #define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER))

    #define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})

    struct _test_
    {
    int x;
    int y;
    int z;
    };

    void Assignment(struct _test_ *t)
    {
    t->x = 1;
    t->y = 2;
    t->z = 3;
    }

    void GetheadPoint(int *tz)
    {
    struct _test_ *p;
    int temp = -1;

    p = container_of(tz,struct _test_, z); //根据成员变量的地址获得该结构体的首地址
    temp = p->y; //根据首地址获得其中另外一个成员变量的值

    printf("line31 = %d\n", temp);
    }

    int main(void)
    {
    int temp = -1;

    struct _test_ tmp; //定义一个结构体变量

    Assignment(&tmp); //给这个变量赋值
    GetheadPoint(&tmp.z); //只传给这个函数一个结构体成员变量的地址

    printf("line43 tmp - >x = %d\n", tmp.x);

    return 0;
    }

    运行结果为:

    line31 = 2
    line43 tmp - >x = 1

    大概解释一下:先定义一个结构体并给其赋值,现在 GetheadPoint函数只传入这个结构体的一个子成员变量地址。在 GetheadPoint函数中通过container_of宏来获得此结构体的首指针,通过此首指针即可以获得此结构体的其它子成员的值。

    1、.typeof( ( (type *)0)->member )为取出member成员的变量类型。

    2、定义__mptr指针ptr为指向该成员变量的指针

    3、mptr为member数据类型的常量指针,其指向ptr所指向的变量处

    4、.(char *)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
    5、.({ })这个扩展返回程序块中最后一个表达式的值。




  • 相关阅读:
    LuoguP4463 [集训队互测2012] calc DP+拉格朗日插值
    一些图的计数
    redis补充1之为什么要用 Redis/为什么要用缓存?
    redis补充4之Redis 和 Memcached 的区别和共同点
    redis补充3之为什么要有分布式缓存?/为什么不直接用本地缓存?
    redis补充2之简单说说有哪些本地缓存解决方案?
    1_java语言概述-注释与API文档等
    1_java语言概述-开发环境搭建
    weblogic 2021.4.20 季度补丁
    mysql source输出记录日志
  • 原文地址:https://www.cnblogs.com/linyilong3/p/2425171.html
Copyright © 2011-2022 走看看