如何计算结构的偏移量?在这里解释一下 printf 语句?
How offset of structure is calculated? Explain printf statement here?
#include<stdio.h>
main()
{
unsigned char c;
typedef struct name {
long a;
int b;
long c;
}r;
r re = {3,4,5};
r *na = &re;
printf("%d", *(int*) ((char*)na + (unsigned int) & ( (struct name *)0 )->b));
}
输出:
4
如果有人能详细解释一下 printf 语句在这个 c 程序中的作用,我将不胜感激?据我说 int
是铸造的。然后 char
指针被转换为 na
。但我不明白整个陈述总体上在做什么?在这里做什么铸造? b
不是指针,但它似乎被用作指针。我发现这个问题之一是 c 编程 book.It 似乎是计算结构偏移量,但我仍然不知道如何计算。请帮助我详细了解程序。
代码 &((struct name *)0)->b
确实被称为 "offsetof" 操作,实际上是 well-known C macro.
思路是,如果a
是A
类型的结构,那么&a.b
等于a
的地址加上[=15=的偏移量] 在 a
。由于这里使用 NULL 代替 a
的地址,结果只是 b
在类型 A
的结构中的偏移量。
根据维基百科,
This works by casting a null pointer into a pointer to structure st,
and then obtaining the address of member m within said structure.
While this implementation works correctly in many compilers, it has
undefined behavior according to the C standard,2 since it involves a
dereference of a null pointer (although, one might argue that no
dereferencing takes place, because the whole expression is calculated
at compile time)
所以让我们看一下printf
step-by-step.
中的表达式
表达式(unsigned int) & ( (struct name *)0 )->b))
如上所述计算b
在struct name
中的偏移量并将结果转换为整数。在大多数平台上,结果应等于 sizeof(long)
。
代码中的(char*)na
将na
强制转换为struct name
的指针为char指针。这是必需的,因为 sizeof(char)
可以假定为 1,而 sizeof(*na)
大于 1。我们要做的是使用 *na
的地址作为原始数字地址,而不是做pointer arithmetic,因此如果例如 na==0x1234
,则 ((char*)na + 4)
的结果等于 0x1234 + 4 = 0x1238
。
求和得到一个内存地址。该地址等于对象na
中成员变量b
的地址,类型为char *
。知道了,最后一步是将地址转换回 int *
(因为 b
的类型是 int
)然后取消引用结果(再一次,我们知道它指向b
)。最后的结果是 b
的值,然后打印出来。
#include<stdio.h>
main()
{
unsigned char c;
typedef struct name {
long a;
int b;
long c;
}r;
r re = {3,4,5};
r *na = &re;
printf("%d", *(int*) ((char*)na + (unsigned int) & ( (struct name *)0 )->b));
}
输出:
4
如果有人能详细解释一下 printf 语句在这个 c 程序中的作用,我将不胜感激?据我说 int
是铸造的。然后 char
指针被转换为 na
。但我不明白整个陈述总体上在做什么?在这里做什么铸造? b
不是指针,但它似乎被用作指针。我发现这个问题之一是 c 编程 book.It 似乎是计算结构偏移量,但我仍然不知道如何计算。请帮助我详细了解程序。
代码 &((struct name *)0)->b
确实被称为 "offsetof" 操作,实际上是 well-known C macro.
思路是,如果a
是A
类型的结构,那么&a.b
等于a
的地址加上[=15=的偏移量] 在 a
。由于这里使用 NULL 代替 a
的地址,结果只是 b
在类型 A
的结构中的偏移量。
根据维基百科,
This works by casting a null pointer into a pointer to structure st, and then obtaining the address of member m within said structure. While this implementation works correctly in many compilers, it has undefined behavior according to the C standard,2 since it involves a dereference of a null pointer (although, one might argue that no dereferencing takes place, because the whole expression is calculated at compile time)
所以让我们看一下printf
step-by-step.
表达式(unsigned int) & ( (struct name *)0 )->b))
如上所述计算b
在struct name
中的偏移量并将结果转换为整数。在大多数平台上,结果应等于 sizeof(long)
。
代码中的(char*)na
将na
强制转换为struct name
的指针为char指针。这是必需的,因为 sizeof(char)
可以假定为 1,而 sizeof(*na)
大于 1。我们要做的是使用 *na
的地址作为原始数字地址,而不是做pointer arithmetic,因此如果例如 na==0x1234
,则 ((char*)na + 4)
的结果等于 0x1234 + 4 = 0x1238
。
求和得到一个内存地址。该地址等于对象na
中成员变量b
的地址,类型为char *
。知道了,最后一步是将地址转换回 int *
(因为 b
的类型是 int
)然后取消引用结果(再一次,我们知道它指向b
)。最后的结果是 b
的值,然后打印出来。