尚未定义类型的数组(不完整的元素类型)

时间:2011-02-21 17:22:50

标签: c

是否可以创建已声明但未定义的类型数组?这就是我想做的事情:

typedef struct _indiv indiv;
typedef indiv pop[];

让其他人通过在另一个.c或.h文件中定义struct _indiv(然后将所有内容链接在一起)来决定个人成员实际是什么。

(对于语义,indiv是一个人,pop是一群人。)

但是编译器抱怨道:

error: array type has incomplete element type

我可以用

替换第二个typedef
typedef indiv * pop;

通过访问像p[i]这样的元素(使用pop类型的p)来使用类似于数组的pop,但如果我这样做,编译器会抱怨

error: invalid use of undefined type ‘struct _indiv’
error: dereferencing pointer to incomplete type

我想因为typedef struct _indiv indiv只是一个声明,编译器在编译时(链接之前)不知道struct需要多少空间而且它不喜欢它,因此禁止做我所做的事情我在努力。但我想知道为什么以及是否有可能实现我想要的方式。

由于

3 个答案:

答案 0 :(得分:2)

如果您希望此源文件操作indiv类型的项目,那么您有2个选择。

1)声明结构,但不要定义它。仅使用指向结构的指针。永远不要取消引用它们:

 struct _indiv;
 typedef struct _indiv indiv; 
 typedef indiv * pop;
 //sizeof(_indiv) is not known, how many bytes should we allocate?
 pop p = malloc(N*unknownSize); 
 //this line will fail because it does not know how many bits to copy.
 p[0] = getIndiv();

2)定义完整的结构:

 struct _indiv
 {
    int id;
    char* name; 
    /*...*/
 };
 typedef struct _indiv indiv; 
 typedef indiv * pop;
 pop p = malloc(N*sizeof(indiv));
 //Now this line can work.
 p[0] = getIndiv();

定义虚拟'indiv'的建议很糟糕:

 --- file1.c

 struct _indiv
 {
    char dummy;
 };
 typedef struct _indiv indiv; 
 typedef indiv * pop;
 pop p = malloc(N*sizeof(indiv));  //this will allocate N bytes.
 //This will generate code that copies one byte of data.
 p[0] = getIndiv();

 ---realIndiv.c

 typedef struct _indiv
 {
    int id;
    char* name; 
    /*...*/
 } indiv;
 indiv getIndiv();
 {
    indiv i = /* whatever */;
    return i;    //this will return 8+ bytes.
 }   

执行此操作时,第一个文件将操作与“真实”indiv结构不同大小的项目,并且您肯定会遇到意外行为。

答案 1 :(得分:1)

你是对的,编译器不知道不完整类型的大小(在你的例子中,struct _indiv是一个不完整的类型),这就是你不能声明这种类型的变量的原因。这包括创建这种类型的数组。

然而,这并不重要,因为如果你没有完整的类型定义,那么你无论如何也无法合理地访问其成员:如果你写p[i].foo,你怎么知道如果类型实际上有一个名为foo的成员,如果它有,那么它是什么类型的?

如果您希望在另一个struct文件中定义.c类型的成员(这称为“opaque类型”),那么您必须只创建和处理指向该结构的指针。您的其他.c应包含实际访问struct本身的所有代码。只有不完整类型的文件将包含如下代码:

indiv *i1, *i2;

i1 = new_individual("foo"); /* Create an individual */
i2 = new_individual("bar");

print_individual(i1);

...包含struct完整定义的源文件将包含new_individual()print_individual()等的实现。

根据这种方案,处理人口的最简单方法是使其成为指向indiv结构的指针数组。

答案 2 :(得分:0)

您只能将指针数组定义为未定义的类型,因为您不知道该类型的大小。

请注意,在C语言中,您可以在许多地方以不同方式定义相同的结构。您可以使用此技术:无论如何只需定义您的结构,然后您就可以自由地定义和使用指向该类型的指针。然后在其他地方定义具有相同名称的真实结构。当你只使用void*的数组时,你也会得到同样的效果。