offsetof宏和container_of宏

offsetof宏

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

功能:

可以用来求一个结构体成员变量的偏移值

测试代码

#include

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

typedef struct
{
    char name[50];
    int  index;
    float ff;
    double dd;
    long   ll;
}TEST_T;


int main()
{
   TEST_T t = {0};
   printf("%d,%d\n", offsetof(TEST_T, name), (char*)&t.name - (char*)&t);
   printf("%d,%d\n", offsetof(TEST_T, index), (char*)&t.index - (char*)&t);
   printf("%d,%d\n", offsetof(TEST_T, ff), (char*)&t.ff - (char*)&t);
   printf("%d,%d\n", offsetof(TEST_T, dd), (char*)&t.dd - (char*)&t);
   printf("%d,%d\n", offsetof(TEST_T, ll), (char*)&t.ll - (char*)&t);

}

结果

在这里插入图片描述

container_of宏

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

/*
1、const typeof( ((type *)0->member ) *__mptr = (ptr);声明一个与成员member同一个类型的指针常量 *__mptr,并初始化为ptr.typeof用于取变量类型

2、(type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址减去member在该struct中的偏移量得到的地址, 再转换成type型指针. 该指针就是member的入口地址了.
*/

功能:

container_of可以根据一个结构体变量中的一个成员变量的地址来获取指向整个结构体变量地址的功能。

测试代码

#include

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


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

typedef struct
{
    char name[50];
    int  index;
    float ff;
    double dd;
    long   ll;
}TEST_T;


int main()
{
   TEST_T t = {0};
   printf("TEST_T:%p\n", &t);

   printf("Contain:%p\n",container_of(&t.index, TEST_T, index));


}
~               

结果

在这里插入图片描述

你可能感兴趣的:(C语言)