C语言中的嵌套链表

C语言中的嵌套链表,c,list,nested,structure,C,List,Nested,Structure,我正在尝试用C实现一个嵌套的链表,它将用于层次菜单。然而,GCC(v4.9.3-1)正在抱怨嵌套结构,我不知道如何解决这个问题。以下是最小(非)工作示例 这种嵌套在C语言中可能吗 main.c #include "menu.h" int main(void) { Init_Menu(); return 0; } #include "menu.h" MenuItem_t LVL_0_MainMenu = { .size = 0, }; MenuItem_t LVL_

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

这种嵌套在C语言中可能吗

main.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
菜单.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
菜单.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);
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);
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;  

根据@bolov和@sps的回答(再次感谢他们两人),以下是最简单的工作示例:

main.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
菜单.c

#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
#include "menu.h"

int main(void) {
    Init_Menu();
    return 0;
}
#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++;
}
菜单.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);
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);
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;  

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

您需要对其内部使用的类型使用
struct
,即使稍后键入def也是如此

例如,这不起作用:

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)+填充
。你看到问题了吗?您所能做的就是有一个指向
X
的指针,但在
X
中没有对象
X

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

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

当您需要管理内存时,它会变得更加复杂(
malloc
/
free
fun),但您无法避免它。

首先,您无法做到

typedef struct {
    SomeName_t some_var;
} SomeName_t;
你需要这样做

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

struct foo {
    struct foo foo_arr[10];      /* Will give error */
    struct foo *foo_ptr_arr[10]; /* Legal */
}; 
但是,我不认为您的
子成员应该是struct数组的原因。因为,正如在
menu.c
中所看到的,您正在

    parent->children[parent->size] = child;
其中
子项的类型为
MenuItem\u t*
。因此,我认为您基本上希望
MenuItem\u t.children
成为
MenuItem\u t*
的数组,而不是
MenuItem\u t
的数组

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

菜单.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);
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);
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;  

遵循C链表的任何教程。您将看到如何定义节点结构。
GCC(v4.9.3-1)正在向嵌套结构投诉
您可以引用这些“投诉”吗?每当你发布一个包含错误/警告信息的问题时,你应该将其包括在内,这样人们就不必猜测问题是什么。谢谢你的建议。我会记住这一点,以便将来提问!我现在不会发布错误,因为博洛夫和sps已经回答了我的问题。一旦我测试了所有东西,我会在我的第一篇文章中发布一个完整的解决方案。我同意你不喜欢那种形式。。。我删除了一个
typedef
,并在所有
MenuItem
之前添加了
struct
关键字,这确实是grossI修复了它。现在,GCC向array
struct MenuItem\t children[10]
投诉,错误如下:array类型的元素类型不完整。@Marko您不能这样做。想想看:
MenuItem\u t
的大小是多少?我真正想要的是存储指向其他(预定义数量的)
MenuItem\u t
变量的指针数组。这能做到吗?至于“typedef表单”,我没有喜欢/不喜欢任何表单的经验,我只是使用一种为微控制器编写头文件的程序员使用的表单:)谢谢你的回答。我编辑了我的第一篇文章,其中包括了这些解决方案。