【问题标题】:assignment from incompatible pointer type/deref pointer to incomplete type从不兼容的指针类型/deref 指针到不完整类型的赋值
【发布时间】:2013-12-12 13:36:41
【问题描述】:

我有这个二叉树,其中每个结构,我们称它们为 A,都有另一个结构类型的指针,我们称它们为 B,指向另一个结构类型 B,依此类推(形成结构类型 B 的链表)。

图片:

(A)
 /\
 (A)->(B)->(B)->(B)->||

问题,我不确定。我收到一条错误消息:

AddRemove.c: In function ‘AddRemove’:
AddRemove.c:21: warning: assignment from incompatible pointer type
AddRemove.c:22: error: dereferencing pointer to incomplete type
AddRemove.c:23: error: dereferencing pointer to incomplete type
AddRemove.c:24: error: dereferencing pointer to incomplete type
AddRemove.c:26: error: dereferencing pointer to incomplete type

代码:

struct A{
//other variables
struct A *left,*right;
struct B *queue;         
}*rootT;

struct B{
//other variables
struct B *next;
};

void AddRemove(struct A *aNode, struct B *bNode){
/*aNode is the memory location of the struct node (A) in the picture and bNode is
 a struct node that we want to add to the linkedlist.*/
struct B *Bptr; //Used to go through the linkedlist of struct type B
if(aNode->queue==NULL){ /*If the pointer of node (A) is null then we have the
pointer point to bNode, the node that we wanted to add.*/
    aNode->queue=bNode;
    bNode->next=NULL;
}
else{
    Bptr=aNode->queue; /*Otherwise have the temp pointer point to what
 node (A)'s pointer points to, which should be the first struct type (B)*/
    while(Bptr->next!=NULL){ /*Keep pointing to the next struct of type B until 
we hit the end*/
        Bptr=Bptr->next;
    }
    Bptr->next=bNode;
}
}

【问题讨论】:

  • 在定义struct A之前添加声明:struct B;
  • 这并没有改变我收到的错误。我应该提到这些结构声明在一个单独的 .h 文件中。
  • 您是否在此源代码中包含标头?如果没有,您需要这样做。如果您不将它们包含在翻译单元中,编译器将无法预测类型。
  • 是的,我把它包括在内,这不是问题。

标签: c pointers struct reference dereference


【解决方案1】:

缺少分号:

struct B{
    //other variables
    struct B *next;
};
 ^

另外,由于您在结构定义中使用了不完整的类型,您应该使用typedef

typedef struct A A;
typedef struct B B;

struct A {
    //other variables
    A *left,*right;
    B *queue;         
} *rootT;

struct B {
    //other variables
    B *next;
};

【讨论】:

  • 如果缺少分号,编译器会给出不同的错误。完全允许在最初编写的指针中使用struct Astruct B;没有强制使用您显示的typedefs。它们是个好主意,尽管 Linux 内核不使用它们(所以不是每个人都同意)。但是,您需要清楚“必须更改”和“可以/应该更改”之间的区别。你确实说“应该”,但你并没有真正解释。
  • 也许我找错树了。我认为当你从另一个引用一个时它是必需的,但也许只有当它是相互交叉引用时。我希望您对不包含标题的看法是正确的。
  • 如果struct X 引用在文件范围内(不在函数内;不在函数原型内),那么基本上你可以在任何地方提及struct X,这表明存在结构类型@ 987654329@,您可以使用它来定义指向该类型的指针,而无需任何进一步的细节。要定义struct X 类型的实际变量,必须提供完整类型。 typedef 名称和结构标记都具有范围。 [...继续...]
  • [...continuation...] 如果您在函数内部定义了一对相互递归的结构类型,那么您编写 struct X; struct Y { ...; struct X *xp; }; struct X { ...; struct Y *yp; } 以确保 @ 987654333@ 指向后面的struct X,而不是之前在文件范围内定义的其他struct X。使用struct X 时不需要typedef,但如果你想写:typedef struct X X; typedef struct Y Y; struct X { ...; Y *yp; }; struct Y { ...; X *xp; };
  • 我实际上有 ;在我的代码中,我只是在stackoverflow上省略了它。无论如何,有人有任何想法吗?我也包含了标题。
猜你喜欢
  • 1970-01-01
  • 2019-08-09
  • 2021-04-07
  • 2021-06-07
  • 2020-12-07
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多