Typedef,标记和未标记的结构以及不兼容的指针类型

时间:2012-10-03 12:51:11

标签: c struct typedef

考虑以下C代码段:

typedef struct node{
    int val;
    struct node* left;
    struct node* right;
}node;

void inorderTraversal(node *p){
    inorderTraversal(p->left);
    printf("%d",p->val);
    inorderTraversal(p->right);
}

如果我只编写typedef struct而不是typedef struct node,当我在inorderTraversal(root)中调用main()时,会收到一条警告,说“传递不兼容指针类型的参数”。为什么即使程序没有显示任何错误,我也会收到此警告?

3 个答案:

答案 0 :(得分:10)

如果您没有为结构提供标签名称,

struct node* left;
结构定义中的

声明了一个新的(不完整的)类型struct node。因此,当您将指针传递给期望node*的那个(不完整)类型时,您将传递一个不兼容类型的指针。

当您定义的结构具有指向同一类型的指针的成员时,您必须能够在定义中命名该类型,因此该类型必须在范围内。

如果您为struct提供了一个名称,那么该类型就是 - 从该点开始 - 在范围内,可以作为struct node引用(如果尚未完成)(如果标记为{{ 1}})。在typedef完成后,可以将该类型称为nodestruct node,无论您喜欢哪种。

但是如果你没有给node一个标签,那么在typedef完成之前,类型是匿名的,并且在此之前不能以任何方式引用。而且从那时起行

struct
遇到

struct node *left; 引用的类型都不知道,该行声明了一个新类型struct node,其中没有任何已知的类型。编译器没有理由将该类型与当前正在定义的类型连接。所以在那时,struct node包含一个指向未知不完整类型的指针的成员。现在,在struct,当您致电

inorderTraversal

inorderTraversal(p->left); ,根据node *p的定义,node是指向未知不完整类型p->left的指针。如果已创建struct node以便p实际上是指向p->left的指针,那么事情仍然可行(除了可能在指向不同类型的指针具有不同表示的平台上),但是您&#39} ;将指针传递给一种类型,其中指向不同类型的指针。由于一种类型不完整,因此与预期类型不兼容。

答案 1 :(得分:1)

"passing argument of incompatible pointer type"

因为当时节点未知。所以它被认为是一种新型。

struct node{
    int val;
    struct node* left;
    struct node* right;
};

void inorderTraversal(struct node *p){
    inorderTraversal(p->left);
    printf("%d",p->val);
    inorderTraversal(p->right);
}

现在,node在使用之前被声明为struct。即struct node* left;所以没有错误。

请参阅此内容:self referential struct definition?
C structure with pointer to self

答案 2 :(得分:-2)

您无法创建匿名typedef,它必须具有名称。 C不支持匿名struct类型。

GCC扩展程序将启用该功能:-fms-extensions