1、前言
在c语言结构中,由于字节对齐问题,成员的地址不能直接根据数据类型的大小计算,宏offsetof可以获得结构成员相对于结构起始地址的字节偏移。
2、实现offsetof宏
c标准库中的offsetof声明必须包括头文件stddef.h :
size_toffsetof(type,member ); 参数:
类型:结构类型
成员:结构成员的名称
返回值:
返回size_t类型的值,指示类型的成员的偏移
此宏在Linux内核源中实现如下:
#defineoffsetof(type,MEMBER ) ) size_t ) ) TYPE * )0) -为什么可以在MEMBER )上的宏中获取具有结构的成员的偏移地址? 首先,偏移地址的计算方法如下。
当前成员地址-结构起始地址=偏移地址
offsetof宏强制将0地址转换为(TYPE * )类型。 也就是说,结构的起始地址为0,因此根据偏移地址的计算方法,可以看到当前成员的地址也等于偏移地址。 因此,如果宏offsetof检索并返回成员的地址,则会得到一个成员的偏移地址。 返回值为size_t型,需要注意
3、实例
以下是offsetof的使用示例。 代码如下。
# include stdio.h # include stddef.h # include stdlib.hstructs { inti; char c; 双精度d; char a[]; (; intmain(intargc,char *argv[] ) printf(sizeof ) structs ) %ZD(n ),sizeof (structs ) ); printf(offsets:I=%ZD; c=%zd; d=%zd; a=%zd.n ',offsetof (结构,I ),offsetof (结构,c ),offsetof (结构,d ),offsetof (结构,a )。 用gcc编译,结果如下。
为了字节对齐,结构体s的大小为16字节。 假设结构起始地址从0开始,int类型占用4个字节,因此地址0到3用于变量I,char类型用于1字节,地址4用于变量c。 因为需要字节对齐,双精度类型的起始地址必须是8的整数倍,所以地址5到7被填充,双精度类型占用8字节。 在变量d中使用地址8到地址15,并且a的地址从地址16开始,以使得通过宏offsetof可以获得结构成员的偏移地址。
参考:
33559 www.run OOB.com/c编程/c-macro-offset of.html
3359 www.cn blogs.com/liti feng/p/7685378.html
转载于:https://www.cn blogs.com/cqlismy/p/11428859.html