结构,包括,前瞻性声明...... C.

时间:2017-01-31 15:00:39

标签: c struct typedef

我再次陷入困境,因为结构引用了自己...... 我知道有关于这个问题的成千上万的问题,我甚至已经自己发布了一个! 我无法弄明白!我希望这次我能理解......

我有3个结构

    //file.h
    #ifndef _FILE
    #define _FILE

    #include "virtuald.h"

    typedef struct directory directory;

    struct file {
        directory* d;
    };
    file* createFile(virtuald*, directory*);

    #endif

    //directory.h
    #ifndef _DIR
    #define _DIR

    #include "file.h"

    struct directory {
        struct directory* father;
        file** listf;
        struct directory** listd;
    };
    directory* createDir(int, char*, int, directory*);

    #endif

    //virtualD.h
    #ifndef _VIR
    #define _VIR

    #include "directory.h"
    typedef struct file file;
    typedef virtuald {
        file** listf;
        directory** listd;
    }virtuald;
    int writeDir(int, directory*);

    #endif

如何管理包含和转发声明?我已经测试了很多东西,但我现在完全失去了。我以为这会有用!

我遇到了很多错误: - 在directory.h中:未知类型名称' file'和'目录' - 在virtuald.h中:未知类型名称'目录'

顺便说一下我用-Wall -Werror -ansi -pedantic进行编译

谢谢

3 个答案:

答案 0 :(得分:2)

规则#1:保持一致!

您似乎在typedef struct A A;struct A之间进行了备用声明(然后在struct之后不使用A。)

我建议你在上一个问题上建议你删除typedef !! 他们似乎只会让你感到困惑。

所以,让我们举一个非常简单的例子。

这样做:

struct declaration(和definition):simple,no typedef:

struct A {
   int x; // whatever
   int y; // whatever
   // ... etc
};

结构类型的用法:关键字struct后跟结构名称:

struct A a;
a.x = 24;
a.y = 42;

(转发)声明:

struct A;

那就是它。所有你必须知道的。 忘记typedef 始终在结构名称前使用关键字struct

你如何应用这个你的例子?让我们来看你的第一个file

使用类型directoryvirtuald仅作为指针,所以您需要的是它们的前向声明:

struct directory;
struct virtuald;

定义你的结构,声明你的功能。在命名结构类型时始终使用关键字struct

struct file {
    struct directory* d;
//  ^~~~~~
//  struct keyword
};

struct file* createFile(struct virtuald*, struct directory*);
//^~~~                  ^~~~~             ^~~~~~
// struct keyword for each naming of a struct type

全部放在一起:

// file file.h
struct directory;
struct virtuald;

struct file {
    directory* d;
};
struct file* createFile(struct virtuald*, struct directory*);

答案 1 :(得分:0)

如果您只使用指针,则告诉编译器有这样的结构就足够了。例如:

//file.h
struct directory;
struct virtuald;
struct file {
    struct directory* d;
};
struct file* createFile(struct virtuald*, struct directory*);

//directory.h
struct file;
struct directory {
    struct directory* father;
    struct file** listf;
    struct directory** listd;
};

//virtualD.h
struct file;
struct directory;
struct virtuald {
    struct file** listf;
    struct directory** listd;
};
int writeDir(int, struct directory*);

答案 2 :(得分:0)

我建议采用以下做法。

有2个包含文件,一个“公共”和一个“私有”。

public one(whatever.h)定义了公共API, 私有的(也许是什么是P.h)定义了什么 需要实施。

所以,例如:

--------- whatever.h ------

#ifndef INCLUDED_WHATEVER_H
#define INCLUDED_WHATEVER_H

typedef struct VirtualDir VirtualDir;
typedef struct Directory  Directory;
typedef struct File       File;
extern File * createFile ( VirtualDir * v, Directory * d );

#endif

------ whateverP.h ------

#ifndef INCLUDED_WHATEVER_P_H
#define INCLUDED_WHATEVER_P_H
#include "whatever.h"

struct VirtualDir {
     /* whatever fields it has */
};

struct Directory {
     /* whatever fields it has */
};

struct File {
     /* whatever fields it has */
};

#endif

----- whatever.c -----

#include "whateverP.h"

extern File * createFile (
        VirtualDir * v,
        Directory *  d
) {
     /* whatever code goes here */
}

-----什么东西都是什么?-----

#include "whatever.h"

File * f = createFile ( blah, bleah );

如果File,VirtualDir和Directory在不同的源文件中实现,则规则仍然有效:blah.h包含公共API,blahP.h包含私有实现细节。