在结构中设置 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_t
s MiddleEast
、SouthernEurope
和 Egypt
,我可以成功将第一个连接设置为 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)
释放内存。
对于类似风险的游戏,我有一个针对每个区域的结构,每个区域都需要有一个相关区域的列表,部队可以从母区域进入。
理论上是这样的
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_t
s MiddleEast
、SouthernEurope
和 Egypt
,我可以成功将第一个连接设置为 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)
释放内存。