1.offsetof函数的定义
offsetof经常用于结构体变量中,用于计算结构体中某个成员的地址相对于该结构体起始地址的偏移量。
1.offsetof定义在c语言库文件stddef.h中。
2.offsetof有两个参数,type为类型,member为成员名。
3.offsetof的返回值为size_t :
在64位操作系统下,其含义为long long unsigned int
在32位操作系统下,其含义为unsigned int
#include <stddef.h>
#include<stdio.h>
struct S
{
double a;
int b;
char c;
};
int main()
{
printf("S 结构中的 a 偏移 = %d 字节。\n", (int)offsetof(struct S,a));
printf("S 结构中的 b 偏移 = %d 字节。\n", (int)offsetof(struct S,b));
printf("S 结构中的 c 偏移 = %d 字节。\n", (int)offsetof(struct S,c));
}
具体结果为什么是这样可移步到我的另一篇博客:结构体内存对齐
2.offsetof函数的模拟实现
struct Stu
{
int a;//0~3
char c;//4
double d;//8~15
};
#define OFFSETOF(struct_type, mem_name) (int)&(((struct_type*)0)->mem_name)
int main()
{
printf("%d\n", OFFSETOF(struct Stu, a));
printf("%d\n", OFFSETOF(struct Stu, c));
printf("%d\n", OFFSETOF(struct Stu, d));
return 0;
}
我们假设结构体起始地址就是0,这样其成员的地址取出来再强制类型转换为int便可以表示结构体中某个成员相对于起始位置的偏移量。
#define offsetof(StructType, MemberName) (size_t)&(((StructType *)0)->MemberName)
struct StructType
{
int a;//0~3
char c;//4
//5~7
double d;//8~15
};
int main()
{
printf("%d\n", offsetof(struct StructType, a));
printf("%d\n", offsetof(struct StructType, c));
printf("%d\n", offsetof(struct StructType, d));
return 0;
}
StructType是结构体类型名,MemberName是成员名。具体操作方法是:
1、先将0转换为一个结构体类型的指针,相当于某个结构体的首地址是0。此时,每一个成员的偏移量就成了相对0的偏移量,这样就不需要减去首地址了。
2、对该指针用->访问其成员,并取出地址,由于结构体起始地址为0,此时成员偏移量直接相当于对0的偏移量,所以得到的值直接就是对首地址的偏移量。
3、取出该成员的地址,强转成size_t并打印,就求出了这个偏移量。