教你一行代码计算结构体元素偏移量,((int) &((type *)0)->member)解析

百度百科中,这样描述"结构体":“结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。结构体类型不是由系统定义好的,而是需要程序设计者自己定义的。C语言提供了关键字Struct来标识所定义的结构体类型。”

在实际的工程项目中,结构体可以说无处不在,不管在哪种软件框架设计中,都会有它的身影。尤其在模块化的软件设计中,常常需要使用Struct结构描述要抽象的对象

举例:描述一个学生的信息元素如图

/* 用一个结构体描述学生各科成绩 */ 
struct Score_detail
{
    float math_score;
    float chinese_score;
    float english_score;
    float chemistry_score;
    float physical_score;
    float geography_score;
};

/* 用一个结构体描述学生 */ 
struct Student
{
  char name[20];  //姓名
  uint32 id;      //学号
  uint32 age;     //年龄
  uint16 score;   //总成绩
  struct Score_detail subject_score; //各科成绩
  char sex;       //性别
};

如果定义一个struct Student类型的变量AoTeMan

 元素实际仅需要57 Byte空间,由于数据对齐(Align = 4 Byte),变量AoTeMan实际消耗了60 Byte字节空间。

计算结构体原理可参考:内存对齐三原则简洁懂,终极计算小技巧-CSDN博客

结构体元素id相对起始地址的偏移量为20,最直接的计算方法:

idOffset = (uint32)(&AoTeMan.id) - (uint32)(&AoTeMan);

 那么有没有更方便的计算方法呢

  1. 采用宏定义方法
/* 定义一个宏,计算各成员相对于结构体起始地址的偏移量 */
#define  offsetof(type,member)   ((int) &((type *)0)->member)

如上的宏如何理解?

  1. ((type*)0):转换成type类型的结构体指针,且起始地址为0;
  2. (((type*)0)->member):引用结构体member成员;
  3. &(((type*)0)->member):取成员member地址;
  4. ((int)&(((type*)0)->member)):将获取的地址强制转换成int类型。

        2.采用函数方法

为了得到确切的偏移量,可以使用offsetof宏,它定义在<stddef.h>头文件中:

#include <stddef.h>

// ... 其他代码 ...

printf("Offset of sex in Student: %zu\n", offsetof(struct Student, sex));

运行上面的代码会给sex成员在Student结构体中的确切偏移量。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值