1

有没有办法创建一个结构,并在 C 中创建一个相同类型的结构的数组?

例如

typedef struct Vertex{
    char letter;
    Vertex edges[];
}Vertex; 

我需要在同一个结构中的结构数组。这在 C 中是否有可能?

4

4 回答 4

3

你可以这样做:

typedef struct _Vertex {
    char letter;
    struct _Vertex* pEdges;
} Vertex; 

Vertix v;
v.pEdges = (Vertex*)malloc(sizeof(Vertex) * n);
v.pEdges[0].letter = '0';

您需要一些方法来了解/跟踪每个数组中有多少项目。

于 2012-11-17T01:55:53.553 回答
1

让我们假设一下,根据您对不同答案的评论,我知道您真正在寻找什么:一种将有限数量的顶点结构引用为某个顶点的边的方法,并且必须为所有顶点记录复制在你的有限集中。

假设它是一个 Vertex 结构的线性列表;特定大小的已分配数组,(或通过realloc()算法不断扩展):

-----------------------------------------
| Vertex[0] | Vertex[1] | Vertex[2] ... |
-----------------------------------------

现在假设在上述每一项的末尾,您需要某种方式来调和

Vertex    Edges
------    -------
[0]       [1],[2]
[1]       [0],[2]
[2]       [0],[1]

很抱歉使用了一个简单的三角形,但这是我能想到的最简单的例子。无论如何继续前进。如果这是您正在寻找的模型,您可以按如下方式定义您的顶点结构:

typedef struct Vertex
{
    char value;     // node 'value'
    int n;          // number of edge indices.
    int *edges;     // dynamic edge index list. [0..(n-1)]
} Vertex;

在定义上述示例时,您将执行以下操作。

  1. 确定全局列表中的哪些顶点条目是当前条目的边。
  2. 分配一个动态索引列表来保存这些边缘“id”的插槽。
  3. 将每个边顶点索引分配到您的索引列表中。

一个简单(非常)的例子是有保证的:

Vertex vtx[3];

// wire vtx[1] and vtx[2] as edges of vtx[0].
vtx[0].value = 'a';
vtx[0].n = 2;
vtx[0].edges = malloc(2 * sizeof(int));
vtx[0].edges[0] = 1;
vtx[0].edges[1] = 2;


// wire vtx[0] and vtx[2] as edges of vtx[1].
vtx[1].value = 'b';
vtx[1].n = 2;
vtx[1].edges = malloc(2 * sizeof(int));
vtx[1].edges[0] = 0;
vtx[1].edges[1] = 2;


// wire vtx[0] and vtx[1] as edges of vtx[2].
vtx[2].value = 'c';
vtx[2].n = 2;
vtx[2].edges = malloc(2 * sizeof(int));
vtx[2].edges[0] = 0;
vtx[2].edges[1] = 1;

所以假设你有 vtx[0]。你如何到达他的第一个边缘?

Vertex *edge = vtx[ vtx[0].edges[0] ];

从那里您可以移动到边缘的第一个边缘

edge = vtx[ edge->edges[0] ];

等等。一张图抵不过一千个字:

-------------------------------------
| Vertex[0] | Vertex[1] | Vertex[2] |
| value = a | value = b | value = c |
| count = 2 | count = 2 | count = 2 |
|-----------|-----------|-----------|
|edges[0]=1 |edges[0]=0 |edges[0]=0 |
|edges[1]=2 |edges[1]=2 |edges[1]=1 |
-------------------------------------

清理需要您free()在全局列表的每个顶点中的索引列表指针。如果全局列表本身是动态分配的,那么你free()也是。在我们上面的示例中,它不是。

我希望至少能让您了解如何做到这一点,而不必去 malloc-nutz 和到处复制数据。总之,在此示例中,可以利用顶点节点列表来维护您真正想要的信息(边),而无需复制顶点节点。

于 2012-11-17T02:35:48.923 回答
1

就像 Jonathan Wood 和 ouah 说的那样去做。在 C 中,我们不能将数组(实际上是结构本身)放入结构中。但是,指向结构的指针会很好地工作。例如,当我们用C实现一个列表时,我们经常使用如下结构:

struct listname{
    void *value;
    struct listname *next;
}

然后,为了放置一个数组,将一个指向结构数组的指针放入其中。

于 2012-11-17T06:10:31.527 回答
0
typedef struct Vertex{
   char letter;
   struct Vertex *edges;
   int n;
}Vertex; 

或者

typedef struct Vertex Vertex;
struct Vertex{
   char letter;
   Vertex *edges;
   int n;
};

例如:

Vertex bla;
const int n = 42;
bla.n = n;
bla.edges = malloc(n * sizeof (*bla.edges));  
于 2012-11-17T01:49:28.430 回答