struct a
{
struct b
{
int i;
float j;
}x;
struct c
{
int k;
float l;
}y;
}z;
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释我如何找到偏移量,int k
以便我们可以找到地址int i
?
Gan*_*har 38
使用offsetof()
发现,从开始的偏移z
或开始x
.
offsetof()
- 结构构件的偏移量
概要
#include <stddef.h>
size_t offsetof(type, member);
Run Code Online (Sandbox Code Playgroud)
offsetof()
从结构类型的开头返回字段成员的偏移量.
例
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
struct s {
int i;
char c;
double d;
char a[];
};
/* Output is compiler dependent */
printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
(long) offsetof(struct s, i),
(long) offsetof(struct s, c),
(long) offsetof(struct s, d),
(long) offsetof(struct s, a));
printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
exit(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
如果使用GCC编译,您将在Linux上获得以下输出:
offsets: i=0; c=4; d=8 a=16
sizeof(struct s)=16
Run Code Online (Sandbox Code Playgroud)
struct a foo;
printf("offset of k is %d\n", (char *)&foo.y.k - (char *)&foo);
printf("offset of i is %d\n", (char *)&foo.x.i - (char *)&foo);
Run Code Online (Sandbox Code Playgroud)
foo.x.i
指i
结构x
中struct 的字段foo
.
&foo.x.i
为您提供该字段的地址foo.x.i
.同样,&foo.y.k
给你的地址foo.y.k
;
&foo
为您提供结构的地址foo
.
减去的地址foo
从地址foo.x.i
给你从偏移foo
到foo.x.i
.
正如Gangadhar所说,你可以使用offsetof()
宏而不是我给出的指针算法.但是首先要理解指针算法是很好的.
小智 7
问题被问到已经3年了,为了完整起见,我正在添加我的答案.
获得结构成员偏移量的hacky方式就是这样
printf("%p\n", (void*)(&((struct s *)NULL)->i));
Run Code Online (Sandbox Code Playgroud)
它看起来不漂亮,我不能想到纯C中的任何东西(它可以让你获得成员的偏移,而不知道结构的其他任何东西.我相信offsetof
宏是以这种方式定义的.
作为参考,这个技术用在linux内核中,查看container_of
宏:
http://lxr.free-electrons.com/source/scripts/kconfig/list.h#L18
在本文中可以找到更详细的解释:
http://radek.io/2012/11/10/magical-container_of-macro/
正如已经建议的那样,您应该使用offsetof()
from中的宏<stddef.h>
,该宏将偏移量作为size_t
值产生。
例如:
#include <stddef.h>
#include <stdio.h>
#include "struct_a.h" /* Header defining the structure in the question */
int main(void)
{
size_t off_k_y = offsetof(struct c, k);
size_t off_k_z = offsetof(struct a, y.k);
size_t off_i_x = offsetof(struct b, i);
size_t off_i_z = offsetof(struct a, x.i);
printf("k = %zu %zu; i = %zu %zu\n", off_k_y, off_k_z, off_i_x, off_i_z);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出示例:
k = 0 8; i = 0 0
Run Code Online (Sandbox Code Playgroud)