我再次陷入困境,因为结构引用了自己...... 我知道有关于这个问题的成千上万的问题,我甚至已经自己发布了一个! 我无法弄明白!我希望这次我能理解......
我有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进行编译
谢谢
答案 0 :(得分:2)
您似乎在typedef struct A A;
和struct A
之间进行了备用声明(然后在struct
之后不使用A
。)
我建议你在上一个问题上建议你删除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
使用类型directory
和virtuald
仅作为指针,所以您需要的是它们的前向声明:
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包含私有实现细节。