C/C++编程:宏offsetof()

1059 篇文章 286 订阅

理论

C 库宏 offsetof(type, member-designator) 会生成一个类型为 size_t 的整型常量,它是一个结构成员相对于结构开头的字节偏移量。成员是由 member-designator 给定的,结构的名称是在 type 中给定的。

/*
* 参数: type -- 这是一个 class 类型,其中,member-designator 是一个有效的成员指示器。
*       member-designator -- 这是一个 class 类型的成员指示器。
* 返回值: 该宏返回类型为 size_t 的值,表示 type 中成员的偏移量
*/
offsetof(type, member-designator)

实践

#include <stddef.h>
#include <stdio.h>

struct address {
    char name[50];
    char street[50];
    int phone;
};

int main()
{
    printf("address 结构中的 name 偏移 = %d 字节。\n",
           offsetof(struct address, name));

    printf("address 结构中的 street 偏移 = %d 字节。\n",
           offsetof(struct address, street));

    printf("address 结构中的 phone 偏移 = %d 字节。\n",
           offsetof(struct address, phone));

    return(0);
} 

在这里插入图片描述

#include <stddef.h>
#include <stdio.h>

struct MBLOCK {
    size_t signature;
    size_t length;
    union {
        size_t align;
        char  payload[1];	/* actually a bunch of bytes */
    } u;
}MBLOCK;


int main()
{
    printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",
           offsetof( struct MBLOCK, signature));  // 0

    printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, length)); // 8

    printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u));  // 16

    printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u.align));  // 16

    printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u.payload[0])); // 16

    printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u.payload[1])); // 17
    printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u.payload[2])); // 18
    printf("MBLOCK 结构中的 u.payload[12] 偏移 = %lu 字节。\n",
           offsetof(struct MBLOCK, u.payload[12])); // 28
    return(0);
}

在这里插入图片描述

offsetof作用是 相对于结构体开始的内存地址偏移了多少

当然,我们可以给结构体起一个别名,这样就不需要每次都创建一个结构体了(结果和上面是一样的)

#include <stddef.h>
#include <stdio.h>

typedef  struct MBLOCK {
    size_t signature;
    size_t length;
    union {
        size_t align;
        char  payload[1];	/* actually a bunch of bytes */
    } u;
}MBLOCK;


int main()
{
    printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",
           offsetof(  MBLOCK, signature));  // 0

    printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, length)); // 8

    printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u));  // 16

    printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.align));  // 16

    printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[0])); // 16

    printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[1])); // 17
    printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[2])); // 18
    printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[12])); // 28
    return(0);
}


#include <stddef.h>
#include <stdio.h>

typedef  struct MBLOCK {
    size_t signature;
    size_t length;
    union {
        size_t align;
        char  payload[1];	/* actually a bunch of bytes */
    } u;
}MBLOCK;


int main()
{
    printf("MBLOCK 结构中的 signature 偏移 = %lu 字节。\n",
           offsetof(  MBLOCK, signature) + 4);

    printf("MBLOCK 结构中的 length 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, length) + 100); // 108 ----> 它的意思是先找到offsetof( MBLOCK, length),然后在偏移100.不会影响原来的内存

    printf("MBLOCK 结构中的 u 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u));  // 16

    printf("MBLOCK 结构中的 u.align 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.align) );  // 16

    printf("MBLOCK 结构中的 u.payload[0] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[0])); // 16

    printf("MBLOCK 结构中的 u.payload[1] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[1])); // 17
    printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[2])); // 18
    printf("MBLOCK 结构中的 u.payload[2] 偏移 = %lu 字节。\n",
           offsetof( MBLOCK, u.payload[12])); // 28
    return(0);
}


在这里插入图片描述
我们可以使用结果体来找到相对某个内存地址偏移多少

#include <stddef.h>
#include <stdio.h>

typedef  struct MBLOCK {
    size_t signature;
    size_t length;
    union {
        size_t align;
        char  payload[1];	/* actually a bunch of bytes */
    } u;
}MBLOCK;

#define SPACE_FOR(len)	(offsetof(MBLOCK, u.payload[0]) + len)
int main()
{
    printf("相对MBLOCK 结构中的 u.payload[0] 偏移 4字节  = %lu 字节。\n", SPACE_FOR(4));  // 20
    printf("相对MBLOCK 结构中的 u.payload[0] 偏移 84字节 = %lu 字节。\n", SPACE_FOR(84));  // 100
    printf("相对MBLOCK 结构中的 u.payload[0] 偏移 -16字节= %lu 字节。\n", SPACE_FOR(-16));
    return(0);
}


在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值