是否可以创建已声明但未定义的类型数组?这就是我想做的事情:
typedef struct _indiv indiv;
typedef indiv pop[];
让其他人通过在另一个.c或.h文件中定义struct _indiv(然后将所有内容链接在一起)来决定个人成员实际是什么。
(对于语义,indiv是一个人,pop是一群人。)
但是编译器抱怨道:
error: array type has incomplete element type
我可以用
替换第二个typedeftypedef 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需要多少空间而且它不喜欢它,因此禁止做我所做的事情我在努力。但我想知道为什么以及是否有可能实现我想要的方式。
由于
答案 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*
的数组时,你也会得到同样的效果。