如何在C中存储自定义对象(struct)?

时间:2018-05-07 21:52:07

标签: c struct calloc

我想知道如何在C中存储自定义对象(而不是它们的指针)。我创建了一个名为Node的自定义结构

#define MAXQ 100

typedef struct {
  int state[MAXQ];
  int height;
} Node;

(有效)我​​希望将这些节点中的一些存储在容器中(不使用指针,因为它们不存储在别处),所以我可以稍后访问它们。

互联网似乎提示类似calloc()的内容,所以我的最后一次尝试是在this example之后创建一个容器Neighbors,其中numNeighbors只是一个整数:

Node Neighbors = (Node*)calloc(numNeighbors, sizeof(Node));

在汇编时,我从这行说出了一个错误 initializing 'Node' with an expression of incompatible type 'void *'

在我引用此容器的地方(如在Neighbors[i]中)我遇到了错误 subscripted value is not an array, pointer, or vector

由于我被Python宠坏了,我不知道我的语法是否全部错了(它应该告诉你一些东西,我在搜索了大量的教程之后仍然没有,文档,以及malloc()calloc()之类的堆栈流,或者如果我采用完全错误的方法来存储自定义对象(搜索"在C&#34中存储自定义对象;在互联网给出了与iOS和C#无关的结果,所以我真的很感激一些帮助。)

编辑:感谢大家提示,最终编译没有错误!

4 个答案:

答案 0 :(得分:2)

您可以使用自定义结构创建常规数组:

Node Neighbors[10];

然后,您可以像任何其他数组一样引用它们,例如:

Neighbors[3].height = 10;

答案 1 :(得分:2)

如果您的C实现支持C.1999样式VLA,只需定义您的数组。

Node Neighbors[numNeighbors];

(请注意,VLA没有错误报告机制。分配失败会导致未定义的行为,这可能表示为崩溃。)

否则,您将需要动态分配。 calloc是合适的,但它返回一个表示连续分配的指针。

Node *Neighbors = calloc(numNeighbors, sizeof(*Neighbors));

注意,在C语言编程时,不要强制转换malloc / calloc / realloc的结果。这不是必需的,在最坏的情况下,可以掩盖致命错误。

答案 2 :(得分:1)

malloc和calloc用于动态分配,它们需要指针变量。我没有看到你使用动态分配的任何理由。只需定义一个常规数组,直到你有理由不这样做。

#define MAXQ 100
#define NUM_NEIGHBORS 50

typedef struct {
  int state[MAXQ];
  int height;
} Node;

int main(void)
{
  Node Neighbors[NUM_NEIGHBORS];

  Neighbors[0].state[0] = 0;
  Neighbors[0].height = 1;
}

此处NUM_NEIGHBORS需要是常量。 (因此是静态的)如果你想要它是变量或动态的,那么你需要动态分配和指针不可避免地:

#define MAXQ 100

typedef struct {
  int state[MAXQ];
  int height;
} Node;

int main(void)
{
  int numNeighbors = 50;
  Node *Neighbors;

  Neighbors = (Node*)calloc(numNeighbors, sizeof(Node));
  Neighbors[0].state[0] = 0;
  Neighbors[0].height = 1;
}

答案 3 :(得分:1)

  

我想将一些节点存储在一个容器中(不使用指针,因为它们没有存储在别处),所以我可以稍后访问它们。

如果您在编译时知道它们的数量(或至少是合理的最大值);然后你可以创建一个堆栈分配对象的数组。例如,假设您最多可以使用10个对象:

#define MAX_NODES 10

Node nodes[MAX_NODES];
int number_nodes = 0;

然后当你添加一个对象时,你保持同步number_nodes(这样你就知道下一个放在哪里)。从技术上讲,你总是有10个,但你只使用你想要/需要的那个。删除对象是类似的,但如果你想在中间删除一些内容,则会更加复杂。

但是,如果您不知道您将拥有多少(也不是最大值);或者即使你知道但它们太多而无法装入堆叠;然后你被迫使用堆(通常使用malloc()free()):

int number_nodes; // unknown until runtime or too big
Node * nodes = malloc(sizeof(Node) * number_nodes);
...
free(nodes);

在任何情况下,您将在动态分配的内存中使用指针,并且很可能在堆栈的情况下也是如此。

Python正在隐藏并在幕后为你做所有这些舞蹈 - 这是非常有用和省时的,因为你可能已经意识到,只要你不需要对它进行精确控制(阅读:性能)。 / p>