在结构中设置 void* 的第 n 个成员(以及结构名称用法与 typedef)

Setting the nth member of a void* in a struct (and struct name usage vs. typedef)

对于类似风险的游戏,我有一个针对每个区域的结构,每个区域都需要有一个相关区域的列表,部队可以从母区域进入。

理论上是这样的

typedef struct {
    char* name;
    region_t* connections;
} region_t;

然而,这当然是不可能的,因为在解析器到达类型 region_t* 之前 region_t 并不存在。因此我选择使用 void* 代替 region_t*.

typedef struct {
    char* name;
    void* connections;
} region_t;

MiddleEast.connections = malloc(6 * sizeof(void*));
MiddleEast.connections = &SouthernEurope;
MiddleEast.(connections + 1) = &Egypt;

使用 region_ts MiddleEastSouthernEuropeEgypt,我可以成功将第一个连接设置为 Southern Europe,但是当我尝试将 .(connections + 1) 设置为 &Egypt 我得到编译器错误

error: expected identifier before ‘(’ token

如何正确访问下一个内存地址?

解决方案不是void *,而是正确使用结构。

可以在内部引用具有名称的结构。该类型不存在,但命名结构存在,因此您可以编写:

typedef struct region{
    char* name;
    struct region* connections;
} region_t;

您想创建一个空指针数组,而不是空数组。你想遍历 void 指针。

typedef struct {
    char* name;
    void **connections;
} region_t;

MiddleEast.connections = malloc(6 * sizeof(void*));
MiddleEast.connections[0] = &SouthernEurope;
MiddleEast.connections[1] = &Egypt;
free(MiddleEast.connections);

is of course impossible due to the fact that region_t doesn't exist before the parser reaches the type region_t*.

您不能转发声明 typedef,但您可以使用结构来做到这一点。

typedef struct region_s {
   char *name;
   struct region_s *connections;
} region_t;

前向声明在 C 代码中很常见,用于构造链表等。 sizeof(struct region_s *) 已知,struct region_s 指针大小在定义 struct region_s 之前已知,因此您可以:

// forward declaration
struct region_s;
// pointer is ok
struct region_s *regionpointer;
// we can define the structure after using a pointer
struct region_s {
    // you can even point to yourself
    struct region_s *regionpointer;
};
// typedef separated for readbility
typedef struct region_s region_t;

error: expected identifier before ‘(’ token

MiddleEast.(connections + 1) = &Egypt;

.是成员运算符;它获取结构的成员。 . 之后的字符串作为符号。如您所见,MiddleEast 结构中没有名为 (connections 的成员(确切地说,使用 space 作为分隔符),因为这样的名称是不允许的。你想要:

MiddleEast.connections + 1 = &Egypt;

这仍然不起作用,因为 = 的左侧是 MiddleEast.connections 数组中指针的值。您不能分配此值;这是加法的结果。 (同样你不能 int a; a + 5 = 43;)。你想要的是将 MiddleEast.connections 数组中第二个元素的值赋给 &Egypt 的值。所以你需要尊重指针值。

*(MiddleEast.connections + 1) = &Egypt;

或更短且更具可读性,因为 a[b] 等于 *(a + b):

MiddleEast.connections[1] = &Egypt;

开玩笑地说:请永远不要:

1[MiddleEast.connections] = &Egypt;

MiddleEast.connections 是一个 "integral"/whole/standalone 部分,您无法将其分开。

注意做:

MiddleEast.connections = malloc(6 * sizeof(void*));
MiddleEast.connections = &SouthernEurope;

只是内存泄漏,因为您无法再free(MiddleEast.connections)释放内存。