不理解我得到的这个前瞻性声明

时间:2014-11-19 19:08:38

标签: c pointers struct forward-declaration

所以,我有以下.h文件:StudentRosterDef.h和StudentRoster.h

StudentRosterDef.h:

typedef struct Node *NodeP;
typedef struct Student *StudentP;

StudentRoster.h:

typedef struct StudentRoster *StudentRosterP;

//Below prototype creates empty studentroster and returns a NULL pointer
StudentRosterP newStudentRoster();

现在,我有以下.c文件:StudentRoster.c

StudentRoster.c:

#include "StudentRosterDef.h"
#include "StudentRoster.h"

struct StudentRosterP
{
    NodeP root;
};

struct NodeP
{
    StudentP left;
    StudentP right;
};

StudentRosterP newStudentRoster()
{
    StudentRosterP thisRoster = (StudentRosterP) malloc(sizeof(StudentRosterP));
    thisRoster->root = 0x00;
    thisRoster = 0x00;
    return thisRoster;
};

以下是在终端上运行gcc命令后得到的消息:

StudentRoster.c:27:12 : error: incomplete definition type of 'struct StudentRoster'
        thisRoster->root = 0x00;

        ~~~~~~~~^

./StudentRoster.h:14:16: note: forward declaration of 'struct StudentRoster'
    typedef struct StudentRoster *StudentRosterP;
                   ^

1 error generated.

无论如何都不能更改或修改StudentRoster.h文件,因为它是一个提供的文件,并且必须构建.c和其他附带的.h文件以完全符合StudentRoster.h的描述。感谢您提前提供任何帮助!

2 个答案:

答案 0 :(得分:2)

您需要定义类型struct Nodestruct StudentRoster,而不是使用名称指针typedef(struct NodePstruct StudentRosterP),因此以下代码可能是你的意思是:

struct StudentRoster  // No P
{
    NodeP root;
};

struct Node  // No P
{
    StudentP left;
    StudentP right;
};

答案 1 :(得分:0)

你有:

typedef struct StudentRoster *StudentRosterP;

您还有:

struct StudentRosterP
{
    NodeP root;
};

这些类型无关;你需要:

struct StudentRoster // No P at the end here!
{
    NodeP root;
};

冲洗并重复。

(请注意brunocodutra在他的answer中说的与此大致相同,但也许没有说得那么精确或简洁,至少在一开始就没有。)


  

你能解释一下为什么不把Pointer作为结构定义会给我一个错误。

P后缀是人类惯例;编译器不知道约定存在。在您定义struct StudentRosterP时,您仍然没有定义访问struct StudentRoster内部所需的StudentRosterP thisRoster;。这定义了一个变量,它是指向不完整类型struct StudentRoster的指针。只要您不需要访问结构中的任何内容,就可以拥有并使用此类指针。它们是“不透明的类型”并且非常有用。但是使用thisRoster->root尝试访问opaque类型的内部,这不起作用。

我想这只是不喜欢using typedef with pointers的另一个原因,即使我理解你的手与类型名称有关。