【问题标题】:How offset of structure is calculated? Explain printf statement here?如何计算结构的偏移量?在这里解释 printf 语句?
【发布时间】:2016-01-05 18:56:50
【问题描述】:
#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 编程书籍之一中发现了这个问题。似乎是计算结构偏移量,但我仍然不知道如何计算。请帮我详细了解程序。

【问题讨论】:

    标签: c pointers casting printf offset


    【解决方案1】:

    代码&amp;((struct name *)0)-&gt;b确实被称为“offsetof”操作,实际上是well-known C macro

    想法是,如果aA 类型的结构,那么&amp;a.b 等于a 的地址加上ab 的偏移量。由于这里使用 NULL 而不是a 的地址,所以结果只是bA 类型的结构中的偏移量。

    根据维基百科,

    这通过将空指针转换为指向结构 st 的指针来工作, 然后获取成员m在所述结构中的地址。 尽管此实现在许多编译器中都能正常工作,但它具有 根据 C 标准的未定义行为,2 因为它涉及 空指针的取消引用(尽管有人可能会争辩说没有 取消引用发生,因为计算了整个表达式 在编译时)

    那么让我们一步一步看一下printf中的表达式。

    表达式(unsigned int) &amp; ( (struct name *)0 )-&gt;b)) 如上所述计算bstruct name 中的偏移量,并将结果转换为整数。在大多数平台上,结果应该等于sizeof(long)

    代码中的(char*)nana,即指向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 的值,然后打印出来。

    【讨论】:

    • 我的实际问题是理解 printf 语句亲爱的。当你尝试时,我仍然支持你的答案
    • @PunitVara:你还缺少哪些部分?我可以扩展答案。一旦你理解了 offsetof 的东西,剩下的就是简单的指针算法了。
    • 如果您逐步扩展该声明,我真的很感谢您。
    • 很好地分解了指针算法。基本上,这是一种复杂的表达方式printf("%d", na-&gt;b);
    • 谢谢@dbush 为什么以 unsigned int 结尾那是什么目的?
    猜你喜欢
    • 2011-03-20
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 2015-03-15
    • 1970-01-01
    相关资源
    最近更新 更多