为什么包含指向自身的指针的结构不能正常工作?

时间:2015-12-10 19:41:01

标签: c pointers struct

#include <stdio.h>
#include <stdlib.h>
typedef struct minion
{
    int home;
    struct minion *father;  
} Minion;
main()
{
    Minion *dummy = (Minion *)malloc(sizeof(Minion));
    dummy->father = &dummy;
    dummy->home = 0;
    printf("%d %d %d", &dummy, dummy->father, (dummy->father)->father);
}

为什么(dummy->father)->father的值与其他值不同?

输出结果为:

2424368 2424368 43

2 个答案:

答案 0 :(得分:2)

main()

这应该是int main(void)

{
    Minion *dummy = (Minion *)malloc(sizeof(Minion));

这更加清晰可靠地写为:

Minion *dummy = malloc(sizeof *dummy);

...

    dummy->father = &dummy;
    dummy->home = 0;

没关系。

    printf("%d %d %d", &dummy, dummy->father, (dummy->father)->father);

这里有几个问题。

dummy是一个指针对象。 &dummy是该指针对象的地址。指针对象在堆栈上分配,并没有特别的理由关心它的地址。

如果您要打印所分配的Minion对象的地址,请将&dummy更改为dummy;你想要指针对象的

%d仅用于打印int类型的值,而不是指针。要打印指针值,请使用%p,它需要类型为void*的参数,因此通常在打印之前必须将指针值转换为void*。该行应如下所示:

printf("%p %p %p\n",
       (void*)dummy,
       (void*)dummy->father,
       (void*)dummy->father->father);

请注意,我在行尾添加了\n,以便正确打印。我还删除了一组不必要的括号。

}

还有一个小问题,与您的问题无关。为每个typedef类型定义struct是很常见的 - 但这不是必需的。我个人的偏好是省略typedef并按原始名称引用结构类型 - 在本例中为struct minion。它更简单(因为在完全定义之前更容易引用类型)。这是一个更多的打字,但恕我直言,如果结构类型是明显的结构,代码更清晰。 (如果你希望类型是 opaque ,那么使用typedef是有意义的,所以使用该类型的代码不知道它是一个结构。你在这里没有这样做。)

另一方面,许多C程序员更喜欢将typedef用于结构,因为它为单个标识符提供了类型的名称。选择一种风格并保持一致。

答案 1 :(得分:0)

#include <stdio.h>
#include <stdlib.h>
typedef struct minion
{
    int home;
    struct minion *father;  
} Minion;
main()
{
    Minion *dummy = (Minion *)malloc(sizeof(Minion));
    /* dummy->father = &dummy <== already a pointer */
    dummy->father = dummy;
    dummy->home = 0;
    printf("%p %p %p", dummy, dummy->father, (dummy->father)->father);
}