C指针算术,没有结构对象

我认为这是不可能在C,但要求validation这一点。 是否有可能在没有这种types的实际variables的结构成员之间进行算术运算? 例如:

typedef struct _s1 { int a; int b; int c; } T1; 

我想看看“C”成员与结构开始的偏移量。 如果我有变数,这很容易:

 T1 str; int dist = (int)&str.c - (int)&str; 

但是我的结构太大,RAM中没有成员(只在EEPROM中)。 我想做一些地址计算,但不要定义RAM成员。 我可以使用结构指针而不是结构variables(它只需要4字节),但是这个例子对我来说很有意思。

使用offsetof你可以在成员之间进行计算,而不必掌握该types的variables。 所有你需要的是types本身和成员的名字。

注意为什么简单的计算可​​能无法解决:数据alignment。 你不知道你的编译器会在你的结构中填充的填充量,如果你改变了结构,这会导致非常微妙的错误,或者使看起来正确的计算错误。

首先,你将单个地址转换为int 。 我不认为这是一个好主意。 一个int保证至less有2个字节或更多的大小,地址/指针通常是4或8个字节。 把这些int只是不坐。 如果我把它们投到任何东西,我可能会使用unsigned long为32位系统, unsigned long long为64位。 我会使用后者是安全的。
也就是说,我不会投这些地址,只是使用offsetofmacros。

#include <stddef.h>添加到文件中,并使用offsetofmacros,将偏移值转换为size_ttypes,而不是int ,请注意。 它只需使用0作为结构的内存地址,然后返回给定成员的地址,给出实际的偏移量:

 size_t offset = offsetoff(T1, c); //struct, member 

正如Zack在他的评论中指出的那样,答案的下一部分有点不相关,但是对于它包含的链接,为了完整起见,我将把它留在这里 – 因为所有实现都需要offsetof

自己定义一个macros,如果你没有stddef.h出于某种原因(它应该是这样,因为offsetof已经在一段时间内成为标准的一部分:C89以上),就像这样:

 #ifndef offsetof #define offsetof(s, m) ((size_t)&(((s *) 0)->m)) #endif 

这应该做的伎俩,但要小心:这种实现可能会导致未定义的行为。 如何和为什么在这里解释
我已经从我在这里find的stddef.h源文件中获得了上面定义的offsetof ,所以你可以直接下载这个文件,并使用它,而不是在你自己的文件中定义这个macros,但是请记住,你使用的offsetof量不是100%可靠。

无论如何,现在已经足够了,Google上有更多的信息,但是这里有几个链接:

  • GCC文档
  • 有关SO的相关问题
  • 另一个SO问题

您可以使用stddef.h定义的offsetof

我知道这超出了你所问的范围,但在linux内核代码container_ofmacros中有一个有用的offsetofcontainer_of可以返回父结构的地址,给出一个指向其成员的指针:

 #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) 

你可以使用例如:

 // pointer_to_c points to a member of the struct, c in this case // and you want to get the address of the container T1 *container; container = container_of(pointer_to_c, T1, c); 

stddef.h有一个名为offsetof的macros,它给出了一个结构起始位置的偏移量。

 size_t t = offsetof( T1 , c ) ; 

这样你就不必实际声明任何结构variables。

看看数据结构alignment

这是正确的:

 size_t dist = offsetof(struct _s1, c); 

在头文件stddef.h有一个macros; offsetof 。 你可以像这样在你的结构体上使用它:

 int dist = (int)offsetof(T1, c);