C中的嵌套链表

时间:2016-08-08 14:37:35

标签: c list nested structure

我正在尝试在C中实现嵌套链表,它将用于分层菜单。然而,GCC(v4.9.3-1)抱怨嵌套结构,我不知道如何解决这个问题。这是最小(非)工作示例。

这种嵌套在C中是否可行?

的main.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}

menu.c

#include "menu.h"

MenuItem_t LVL_0_MainMenu = {
    .size = 0,
};

MenuItem_t LVL_1_Measurements = {
    .size = 0,
};

void Init_Menu(void) {
    Menu_Add_Child(&LVL_0_MainMenu, &LVL_1_Measurements);
}

void Menu_Add_Child(MenuItem_t *parent, MenuItem_t *child) {
    parent->children[parent->size] = child;
    child->parent = parent;
    parent->size++;
}

menu.h

typedef struct {
    unsigned char size;
    MenuItem_t children[10];
    MenuItem_t *parent;
} MenuItem_t;

extern MenuItem_t LVL_0_MainMenu;
extern MenuItem_t LVL_1_Measurements;

void Init_Menu(void);
void Menu_Add_Child(MenuItem_t *parent, MenuItem_t *child);

基于@bolov和@sps的回答(再次感谢他们两个),这是最小的工作示例:

的main.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}

menu.c

#include "menu.h"

MenuItem_t LVL_0_MainMenu = {
    .size = 0,
};

MenuItem_t LVL_1_Measurements = {
    .size = 0,
};

void Init_Menu(void) {
    Menu_Add_Child(&LVL_0_MainMenu, &LVL_1_Measurements);
}

void Menu_Add_Child(MenuItem_t *parent, MenuItem_t *child) {
    parent->children[parent->size] = child;
    child->parent = parent;
    parent->size++;
}

menu.h

struct MenuItem_t {
    unsigned char size;
    struct MenuItem_t *children[10];
    struct MenuItem_t *parent;
};

typedef struct MenuItem_t MenuItem_t;

extern MenuItem_t LVL_0_MainMenu;
extern MenuItem_t LVL_1_Measurements;

void Init_Menu(void);
void Menu_Add_Child(MenuItem_t *parent, MenuItem_t *child);

此更正程序与原始(非)工作程序之间的区别在于,children数组被定义为指向MenuItem_t类型变量的指针数组,而不是相同类型的变量数组。另一个区别是嵌套列表(在结构内部)也应该包含@bolov解释的关键字struct

2 个答案:

答案 0 :(得分:1)

你需要使用struct作为自身内部使用的类型,即使你稍后输入它也是如此。

E.g。这不起作用:

struct X_ {
  X* next;
};

typedef struct X_ X;

但这会

struct X_ {
  struct X_* next;
};

作为旁注,我真的不喜欢这种形式:

typedef struct {
} X;

我用:

struct X {
};
typedef struct X X;

但也许这只是我更喜欢C++

如果你想使用那个表格,它是一样的:你需要添加struct并且它有效:

typedef struct {
  struct X2* next;
} X2;

关于:

struct X {
   struct X arr[10];
};

你不能拥有它!阵列正是我们理解原因的方式。所以让我们简化:

struct X {
   int a;
   struct X var;
};

这不可能。 X的大小是多少? sizeof(X) = sizeof(int) + sizeof(X) + padding。你看到了问题吗?您所能做的只是指向X的指针,而不是指向X内的对象X

返回你的阵列。你需要动态数组:

struct X {
   struct X* arr;
   int arr_size;
};

由于您需要管理内存(malloc / free有趣),因此变得更加复杂,但您无法避免。

答案 1 :(得分:1)

首先,你做不到,

typedef struct {
    SomeName_t some_var;
} SomeName_t;

您需要这样做,

typedef struct somename {
    struct somename some_var;
} SomeName_t;

此外,struct不能有一个结构本身的成员。但是,struct可以有一个成员,该成员是指向同一结构的指针数组。

struct foo {
    struct foo foo_arr[10];      /* Will give error */
    struct foo *foo_ptr_arr[10]; /* Legal */
}; 

但是,我没有看到你的children成员应该是结构数组的原因。因为,正如menu.c中所见,你正在做

    parent->children[parent->size] = child;

child的类型为MenuItem_t *。所以我认为你基本上希望MenuItem_t.children成为MenuItem_t *的数组,而不是MenuItem_t的数组。

因此,进行此更改可以解决您的问题:

<强> menu.h

typedef struct menuitem {
    unsigned char size;
    /* MenuItem_t children[10]; */  /* Not possible */
    struct menuitem *children[10];  /* This is what you want to do */
    struct menutem *parent;
} MenuItem_t;