我正在尝试初始化(或创建(一个指向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
,使用类似NodeRef
或NodePtr
的东西,在名称中表示它是指向节点的指针,而不是节点。 Apple 的核心基础 API 使用这样的名称(例如CFStringRef
(。 我强烈建议今后通过一项与此类似的公约。 我发布的上述代码可能如下所示:
static struct node nilObj = { 0, "null", "null", &nilObj };
nodeRef nil = &nilObj;
void mklist(nodeRef *n)
{
*n = nil;
}