如何在C中指定静态数组的动态数组? 我想创建一个包含两个静态数组动态数组的结构。
struct indexed_face_set {
double * [3] vertices;
int * [3] faces;
};
这应该包含一个动态的顶点列表,每个顶点有3个双打,还有一个动态的面部列表,每个都有3个整数。
答案 0 :(得分:3)
语法是,C语言的声明方法并不是最干净的C ++继承的...
double (*vertices)[3];
该声明意味着vertices
是指向double [3]
个对象的指针。请注意,需要括号,否则(如double *vertices[3]
中所示)它将表示3 double*
的数组。
过了一段时间,你最终习惯于在表达式上使用倒置的括号方式......
答案 1 :(得分:0)
对于包含两个每个维度为3的数组的结构的特定情况,将数组作为结构的一部分会更简单,而不是单独动态分配它们:
struct indexed_face_set
{
double vertices[3];
int faces[3];
};
但是,当然可能存在处理动态数组分配的情况。在这种情况下,您需要一个指向结构中数组的指针(而不是指针数组)。所以,你需要写:
struct indexed_face_set
{
double (*vertices)[3];
int (*faces)[3];
};
要分配完整的struct indexed_face_set
,您需要使用类似new_indexed_face_set()
的内容,并释放您需要使用destroy_indexed_face_set()
之类的内容:
struct indexed_face_set *new_indexed_face_set(void)
{
struct indexed_face_set *new_ifs = malloc(sizeof(*new_ifs));
if (new_ifs != 0)
{
double (*v)[3] = malloc(sizeof(*v));
int (*f)[3] = malloc(sizeof(*f));
if (v == 0 || f == 0)
{
free(v);
free(f);
free(new_ifs);
new_ifs = 0;
}
else
{
new_ifs->vertices = v;
new_ifs->faces = f;
}
}
return(new_ifs);
}
void destroy_indexed_face_set(struct indexed_face_set *ifs)
{
if (ifs != 0)
{
free(ifs->vertices);
free(ifs->faces);
free(ifs);
}
}
然后你可以像这样使用它:
void play_with_ifs(void)
{
struct indexed_face_set *ifs = new_indexed_face_set();
if (ifs != 0)
{
(*ifs->vertices)[0] = 3.14159;
(*ifs->vertices)[1] = 2.71813;
(*ifs->vertices)[2] = 1.61803;
(*ifs->faces)[0] = 31;
(*ifs->faces)[1] = 30;
(*ifs->faces)[2] = 29;
do_something_fancy(ifs);
destroy_indexed_face_set(ifs);
}
}
请注意,使用指针指向数组的符号是适度混乱的;人们不经常使用它们的一个原因。
您可以将此片段用作标题的正文:
#ifndef DASS_H_INCLUDED
#define DASS_H_INCLUDED
struct indexed_face_set;
extern void play_with_ifs(void);
extern void do_something_fancy(struct indexed_face_set *ifs);
extern void destroy_indexed_face_set(struct indexed_face_set *ifs);
extern struct indexed_face_set *new_indexed_face_set(void);
#endif /* DASS_H_INCLUDED */
不需要任何额外的标题;它不需要这些函数的结构定义的细节。你将它包装在合适的头部防护装置中。
因为上面的代码在使用数组时有点乱,所以大多数人会使用更简单的表示法。上面的标题可以保持不变,但代码可以更改为:
struct indexed_face_set
{
double *vertices;
int *faces;
};
struct indexed_face_set *new_indexed_face_set(void)
{
struct indexed_face_set *new_ifs = malloc(sizeof(*new_ifs));
if (new_ifs != 0)
{
double *v = malloc(3 * sizeof(*v));
int *f = malloc(3 * sizeof(*f));
if (v == 0 || f == 0)
{
free(v);
free(f);
free(new_ifs);
new_ifs = 0;
}
else
{
new_ifs->vertices = v;
new_ifs->faces = f;
}
}
return(new_ifs);
}
void destroy_indexed_face_set(struct indexed_face_set *ifs)
{
if (ifs != 0)
{
free(ifs->vertices);
free(ifs->faces);
free(ifs);
}
}
void play_with_ifs(void)
{
struct indexed_face_set *ifs = new_indexed_face_set();
if (ifs != 0)
{
ifs->vertices[0] = 3.14159;
ifs->vertices[1] = 2.71813;
ifs->vertices[2] = 1.61803;
ifs->faces[0] = 31;
ifs->faces[1] = 30;
ifs->faces[2] = 29;
do_something_fancy(ifs);
destroy_indexed_face_set(ifs);
}
}
这更容易理解和使用,通常被认为是更惯用的C.
由于每个数组的大小是固定的,因此不需要在结构中记录大小。如果尺寸在运行时变化,特别是如果某些索引面集具有8个顶点和6个面(长方体?),那么您可能希望记录结构中数组的大小。您还可以在new_indexed_face_set()
的调用中指定顶点数和面数。