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

时间:2018-12-20 11:01:29

标签: c struct void-pointers

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

理论上,它看起来像

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_tMiddleEastSouthernEurope,可以成功将第一个连接设置为Egypt,但是当我尝试设置Southern Europe.(connections + 1)出现编译器错误

&Egypt

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

2 个答案:

答案 0 :(得分:6)

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

具有名称的

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

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

答案 1 :(得分:1)

您要创建一个空指针数组,而不是一个空数组。您想遍历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);
  

当然不可能,因为在解析器到达region_t *类型之前,region_t不存在。

您不能转发声明typedef,但是可以使用structure来实现。

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

在构造链接列表和类似列表时,前向声明在C代码中很常见。在定义sizeof(struct region_s *)之前,已知struct region_sstruct 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;
  

错误:“(”令牌之前的预期标识符

MiddleEast.(connections + 1) = &Egypt;

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

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是不可分割的“整体” /整体/独立部分。

请注意:

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

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