这是C编程语言中链表的代码。
#include <stdio.h> /* For printf */
#include <stdlib.h> /* For malloc */
typedef struct node {
int data;
struct node *next; /* Pointer to next element in list */
} LLIST;
LLIST *list_add(LLIST **p, int i);
void list_remove(LLIST **p);
LLIST **list_search(LLIST **n, int i);
void list_print(LLIST *n);
代码没有完成,但我认为这对我的问题已经足够了。这里在结构节点的末尾使用“LLIST”,它也在函数list_add
的原型设计中用作返回类型。发生了什么事?
答案 0 :(得分:24)
那是typedef
。它实际上是一次做两件事。首先,它定义了一个结构:
struct node {
int data;
struct node *next;
}
然后执行typedef
:
typedef struct node LLIST;
这意味着LLIST
是一种类型,就像int
或FILE
或char
一样,是struct node
的简写,您的链表节点结构体。没有必要 - 你可以在所有这些地方用LLIST
取代struct node
- 但这会使它更容易阅读,并有助于隐藏最讨厌的最终用户的实施。
答案 1 :(得分:10)
LLIST只是已创建的结构的另一个类型名称。通常,以下格式将创建一个“结构x”类型“NAME”:
typedef struct x { ... } NAME;
答案 2 :(得分:10)
C要求您使用“struct”前缀引用结构,因此引入一个typedef以减少冗长的提及是很常见的。
也就是说,你的struct的声明有两个部分,可以这样重写:
struct node {
int data;
struct node *next; /* pointer to next element in list */
};
typedef struct node LLIST;
所以,LLIST
只是struct node
的另一个名字(感谢Chris Lutz)。
答案 3 :(得分:6)
typedef
在程序中创建一个新的“类型”,因此这些函数的返回值和参数类型只是你的结构。它只是将struct node
用于类型的简写。
如果你要创建一个新节点,你可以这样做(使用类型):
LLIST *node = malloc(sizeof(LLIST));
node->data = 4;
node->next = someOtherItem;
list_add(node, 1)
另外,对于你问题中的函数原型,你真的不需要双指针;由于结构中的数据只是int
,您可以执行类似
LLIST *list_add(int data, int position);
然后list_add
函数将处理分配,将int
复制到结构中并将其添加到链表中。
将其置于某个位置就像将节点前的next
指针更改为新分配的节点的地址一样简单,并将新节点中的next
指针指向在下一个(那个节点之前的节点最初指向的那个)。
请记住(给定其余的函数原型),您必须跟踪指向您创建的每个节点的指针,以便全部删除它们。
我不确定我是否理解搜索功能如何运作。整个事情可以更好地实施。在创建节点时,您不应该拥有来提供节点的位置(如果您指定的节点数比节点数多,那该怎么办?)等等。
答案 4 :(得分:3)
LLIST*
是指向LLIST
结构定义的结构的指针。
你应该做
LLIST* myList = malloc(sizeof(LLIST)*number_of_elements);
为此列表分配一些内存。添加和删除项目需要您使用realloc重新分配内存。我已经为列表编写了一些代码(用数组制作)。
我可能会在我回家后立即发布代码,目前情况并非如此。