`
xinklabi
  • 浏览: 1586937 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

定义计算变量相对于结构体偏移量的宏

 
阅读更多

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

 

struct person {

int a;

int m;

char b;

char c;

};

 

#define FIND(type, member)    (size_t)&(((type *)0)->member)

//这里面size_t这样定义的,typedef unsigned int size_t,定义在stddef.h文件中.

 

int main()

{

int entry1 = FIND(struct person, a);

    int entry2 = FIND(struct person, b);

    int entry3 = FIND(struct person, c);

printf("%d %d %d\n", entry1, entry2, entry3);

}

 

输出:

0    8    9

 

 

说明:

ANSI C标准允许值为0的常量被强制转换成任何一种类型的指针,
并且转换结果是一个NULL指针,因此((type *)0)的结果就是一个类型为type *的NULL指针。
如果利用这个NULL指针来访问type的成员当然是非法的,
但&( ((type *)0)->field )的意图仅仅是计算field字段的地址。
聪明的编译器根本就不生成访问type的代码,
而仅仅是根据type的内存布局和结构体实例首址在编译期计算这个(常量)地址,
这样就完全避免了通过NULL指针访问内存的问题。
又因为首址为0,所以这个地址的值就是字段相对于结构体基址的偏移。
以上方法避免了实例化一个type对象,并且求值在编译期进行,没有运行期负担。

 

在stdlib.h中对NULL如下定义的(可以解释(type *)0):

/* Define NULL pointer value */

#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

分享到:
评论

相关推荐

    结构体偏移.docx

    【结构体偏移】在C语言中,结构体偏移是指结构体内成员变量相对于结构体起始位置的字节距离。这个概念对于理解和优化内存布局、处理指针运算以及理解编译器对结构体的存储策略至关重要。在编程中,尤其是在处理底层...

    C语言中结构体偏移及结构体成员变量访问方式的问题讨论

    注:这里的偏移量指的是相对于结构体起始位置的偏移量。 看到这个问题的时候,我相信不同的人脑中浮现的解决方法可能会有所差异,下面我们分析以下几种可能的解法: 方法1 如果你对c语言的库函数比较熟悉的话,那么...

    高手笔记 结构成员变量偏移量的两个应用

    `offsetof`宏用于计算结构体成员相对于结构体起始地址的偏移量。例如,`offsetof(TYPE, MEMBER)`返回`MEMBER`在`TYPE`结构体内的偏移量(以字节为单位)。然后,通过将该偏移量从指向`MEMBER`的指针中减去,可以得到...

    详解C语言的结构体中成员变量偏移问题

    - 方法1:使用`offsetof`宏,这是一个标准库函数,可以直接计算出成员相对于结构体起始位置的偏移。`offsetof(struct node_t, c)`将返回`c`的偏移量。 - 方法2:手动计算,通过获取成员变量的地址减去结构体的地址...

    C语言之struct大小、首地址与内存对齐[借鉴].pdf

    在main函数中,我们首先打印了结构体的首地址,然后计算了结构体成员dd相对于结构体首地址的偏移量,并将其打印出来。最后,我们计算了结构体的首地址,从dd成员的地址中减去偏移量得出。 本文详细介绍了C语言中...

    编译器数据对齐方式(结构体、类所占空间的计算)

    2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍。如果不够整数倍,编译器会在成员之间插入填充字节(padding bytes),确保每个成员的地址满足对齐条件。 3. 结构体的总大小为结构体最宽基本...

    c语言宏定义技巧,常用宏定义方法

    有时候我们需要知道结构体中某个成员相对于结构体起始位置的偏移量,这可以通过以下宏定义实现: ```c #define FPOS(type, field) \ /*lint-e545*/((dword)&((type*)0)-&gt;field) /*lint+e545*/ ``` 这里`FPOS`宏...

    Linux下的两个经典宏定义.docx

    `offsetof`宏的主要作用是计算一个结构体成员相对于结构体起始位置的偏移量。它的定义如下: ```c #define offsetof(TYPE, MEMBER) ((size_t) ((TYPE *)0)- MEMBER) ``` 这个宏的工作原理是: - `(TYPE *)0`...

    C语言宏定义技巧(常用宏定义)

    此宏可以计算出成员`field`相对于结构体起始位置的偏移量。 #### 六、获取结构体成员的大小 获取结构体成员的大小也很重要,这有助于在动态分配内存时确定所需的空间大小: ```c #define FSIZ(type, field) ...

    宏定义的技巧

    对于结构体中的成员变量,有时候需要知道它们相对于结构体起始位置的偏移量。可以通过以下宏定义来实现这一需求: ```c #define FPOS(type, field) \ /*lint-e545*/ ((dword)&((type*)0)-&gt;field) /*lint+e545*/ ``...

    C语言数据类型大小和结构体中变量的地址分配方法.doc

    如果定义了变量Test t,那么在存储t的i时,X就应该是min(8,sizeof(int))即为4的倍数,即i相对于结构体首地址的偏移量必须是4的倍数,所以t的大小就应该为8字节(在c1和c2后填充了两个字节以满足前述条件)。...

    新手入门易上手的宏定义

    这个宏定义可以帮助程序员轻松获取到结构体中某个字段相对于结构体起始地址的偏移量,这对于处理复杂的数据结构非常有用。 ##### 6. 获取结构体字段大小 类似的,获取结构体字段大小的宏定义也被提及: ```c #...

    C语言常用宏定义技巧

    在处理复杂的数据结构时,有时需要知道某个成员相对于结构体起始位置的偏移量。可以通过以下宏定义实现: ```c #define FPOS(type, field) ((dword)&((type*)0)-&gt;field) ``` 这个宏定义可以计算出指定类型中成员`...

    宏定义使用技巧1

    在处理结构体时,有时我们需要知道某个字段相对于结构体起始位置的偏移量以及该字段所占的字节数。可以通过以下宏来实现: ```c #define FPOS(type, field) \ /*lint -e545*/ ((dword)&((type *)0)-&gt;field) /*lint...

    c语言定义和使用宏定义的技巧

    此宏用于获取结构体中特定成员相对于结构体起始位置的偏移量。这对于低级编程很有用,尤其是在需要手动处理内存布局的情况下。 #### 获取结构体成员的字节数 ```c #define FSIZ(type, field) sizeof(((type*)0)-&gt;...

    嵌入式c宏定义

    在处理复杂的数据结构时,有时需要知道某个字段相对于结构体起始位置的偏移量。可以通过以下方式定义宏来实现这一功能: ```c #define FPOS(type, field) ((dword)&((type *)0)-&gt;field) ``` 此宏接收两个参数:`...

    20个C语言中常用宏定义总结

    **解释**:此宏定义计算结构体成员`field`相对于结构体起始位置的偏移量。`((type*)0)`创建了一个指向零地址的结构体指针,通过`-&gt;field`访问其成员并取地址,即可获得该成员的偏移量。注意,这里的`dword`应该是...

Global site tag (gtag.js) - Google Analytics