C语言 为什么此链表初始化不起作用?



我正在尝试初始化(或创建(一个指向NULL的空节点的链接列表,但它返回了一个错误,我不知道为什么。有人可以帮助我吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
int times;
char name[100];
char number[100];  
struct node* next;
};
typedef struct node* node;
void mklist(node* n) {
(*n)->times = 0;
strcpy((*n)->name, "null");
strcpy((*n)->number, "null");
(*n)->next = (node)NULL;
}
int main(void) {
node n;
mklist(&n);
return 0;
}

所以node实际上是一个指向struct node的指针,非常混乱

typedef struct node* node;

main()中,声明一个指针并将一个指针传递给一个指向mklist()

node n;
mklist(&n);

mklist()中,n实际上是一个指向结构的指针的指针,因此取消引用它,你会得到一个指向结构的指针

void mklist(node* n){
(*n)->times=0;

但是在您的代码中没有任何地方为实际结构分配内存。

当前代码方式最直接的解决方法是添加malloc()

void mklist(node* n) {
*n = malloc(sizeof(*(*n)));
// check for malloc() failure
(*n)->times = 0;
strcpy((*n)->name, "null");
strcpy((*n)->number, "null");
(*n)->next = (node)NULL;
}

您可以在全局范围内轻松执行此操作:

// nil = &nilObj, which means nil->next == nil.
// 
// This way, there's no checking for both 'nil' and 'NULL'!
// 
// As a consequence of this last point, you can make passing 'NULL'
// to most list functions invalid: it just means the user didn't
// use mklist() on every list they needed to manually work with.
static struct node nilObj = { 0, "null", "null", &nilObj };
node nil = &nilObj;
void mklist(node *n)
{
*n = nil;
}

正如Stephen Docy所提到的,使用typedef T *Tname;通常是一个坏主意,因为它隐藏了你正在使用指针的事实,当你使用Tname *n作为(*n)->foo时,这可能会令人困惑(我希望老实说n->foo使用它(。 一些 API 这样做,但它们的方式是表达变量是指向对象的指针而不是对象:而不是Node,使用类似NodeRefNodePtr的东西,在名称中表示它是指向节点的指针,而不是节点。 Apple 的核心基础 API 使用这样的名称(例如CFStringRef(。 我强烈建议今后通过一项与此类似的公约。 我发布的上述代码可能如下所示:

static struct node nilObj = { 0, "null", "null", &nilObj };
nodeRef nil = &nilObj;
void mklist(nodeRef *n)
{
*n = nil;
}

相关内容

  • 没有找到相关文章

最新更新