我正在尝试在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
。
答案 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;