关于您的编译器错误:
int QGetSize(queue *);
ERROR: parse error at near '*'
这可能是因为您没有包含 extern.h,或者如果包含,则未定义“queue”的 typedef。如果 C 找到一个应该是类型但还没有(还)被定义为类型的词,它会非常困惑。
int QGetSize(queue);
ERROR: invalid functions argument declaration
和上面一样。定义必须出现在使用之前。
int QGetSize(struct *);
ERROR: parse error at near '*'
这是无效的。'struct' 不是类型;'struct queue' 是类型。也就是说,您需要在 'struct' 之后指定类型标记才能使其有意义。
int QGetSize(struct);
ERROR: parse error at near ')'
同上。此外,编译器会在“结构”之后期待另一个词,如果没有的话会非常困惑。
int QGetSize(struct queue *);
WARNING: struct declared inside parameter list
这意味着尚未定义类型“结构队列”。它没有。'typedef struct { ... } queue' 与'struct queue { ... }' 不同。
所以这里有一些建议:
首先,标准做法是用“#ifndef”包装头文件的主体,以确保它只被包含一次:
#ifndef __HDR_H
#define __HDR_H
... code goes here ...
#endif
(__HDR_H 必须是唯一的,并且通常是文件名的变体。)
然后,您始终可以将定义类型的标头#include 到使用它们的任何文件中。#ifndef(通常)允许您不受惩罚地包含在内。
其次,你需要弄清楚结构标签和类型定义之间的区别。
结构标记是特定结构定义的名称:
struct queue { ... }; // Defines struct queue
struct queue foo; // foo is a queue structure.
typedef 是现有类型的别名:
typedef int HANDLE; // HANDLE is just another way of saying 'int'
typedef struct queue QUEUE; // QUEUE is shorthand for 'struct queue'
两者是非常不同的东西。第一个定义了特定类型的结构,而第二个为现有类型创建了一个新名称。事实上,您可以将它们组合起来:
typedef struct queue { ... } QUEUE;
你经常想要,特别是如果'struct queue'包含指向另一个'struct queue'的指针。
所以在这个:
QUEUE foo;
struct queue bar;
'foo' 和 'bar' 具有完全相同的类型。
(此外,与此半相关:C 中的常见做法是使 typedef 名称全部大写。)
第三,你应该谨慎使用 typedef。在你的情况下,我建议完全摆脱它,只使用'struct'关键字。这使得知道发生了什么变得容易得多,因为局部结构变量在其声明中具有“结构”,因此不经意的读者可以看到它是一个结构,而不是重命名的 int。
更重要的是,它可以让编译器为您提供更有意义的错误消息。如果结构未定义并且编译器看到如下内容:
int foo(struct bar x);
它知道 bar 是一个结构,所以整个事情是一个参数声明,可以告诉你“struct bar”是未定义的。但是,如果它看到这一点:
int foo(BAR x);
它不知道 BAR 应该是什么,所以错误消息往往是一个很大的 WTF?!?!?!?!?反而。
最后,如果你使用 'struct' 形式,你可以预先声明结构:
struct bar;
int foo (struct bar x);
struct bar { ... };
这很少有必要,但您偶尔会发现自己有一些非常扭曲的循环依赖。在这种情况下,这可以让你摆脱困境。(这也是为什么上面的最后一个编译器警告是警告而不是错误的原因;编译器将未知的结构参数解释为前向声明。这是合法的,但不是一个好主意。)
无论如何,我希望这会有所帮助并祝你好运。