C语言 指向链表开头的指针



我在学习指针时正在练习链表结构,并且在列表中附加项目时遇到问题。这是我的代码

#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int data;
node_t* next;
};
void append(node_t *head, int data) {
if (head == NULL) {
node_t *node = (node_t*)malloc(sizeof(node_t*));
node->data = data;
node->next = NULL;
head = node;
} else {
node_t *node = (node_t*)malloc(sizeof(node_t*));
node->data = data;
node->next = NULL;
if (head->next == NULL) {
head->next = node;
} else {
node_t *current = head;
while (1) {
if (current->next == NULL) {
current->next = node;
break;
}
current = current->next;
}
}
}
}
int main(void) {
node_t *head = NULL;
append(head, 4);
append(head, 6);
printList(head);
return 0;
}

当我这样做时,我的代码会中断head = node;它不会更改mainhead的值。我想我错过了一些东西,但不确定是什么。 提前谢谢你

您正在按函数追加中的值传递指针头。因此,该函数处理传递给它的指针的副本。更改副本不会影响原始指针。要么通过引用传递它,要么从函数返回更新的头。

第一种方法要好得多。

该函数可以如下所示

int append( node_t **head, int data )
{
node_t *node = malloc( sizeof( node_t ) );
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node
{
int data;
node_t *next;
};
int append( node_t **head, int data )
{
node_t *node = malloc( sizeof( node_t ) );
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
void printList( node_t *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
int main(void) 
{
node_t *head = NULL;
const int N = 10;
for ( int i = 0; i < N; i++ )
{
append( &head, i );
}
printList( head );
return 0;
}

它的输出是

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null

似乎问题是您正在按值传递head指针,因此当您在append()中更改它时,您只更改该函数中的局部变量 - 而不是main()中的head变量。

这可能有点令人困惑 - 如果你传递一个指针,你怎么能按值传递?好吧,你可能想看看这个问题:

传递指针参数,按C++值传递吗?

。最重要的是,append()需要采取node_t** head,您将从 Main 与append(&head, 4);调用它。看到它在科利鲁上工作。

此外,您还要为每个节点分配sizeof(node_t*)。您应该分配sizeof(node_t).

它不会改变 main 中头部的值

也不应该!如果在调用append()时 main 中的head值发生了变化,那么您对printList()的调用只会打印列表中的最后一个节点,并且您无法引用列表中的其他节点。

head没有改变的原因在其他答案中已经得到了很好的解释,即你正在按值传递头部指针。请务必了解,main()中的headappend()中的head参数是完全不同的变量。

您按值传递列表的头部,因此append函数无法更新调用者空间中的指针,而指针恰好与head同名。append中的head参数是与main中的head局部变量分开的变量。

应将指针传递给头节点,以便append可以对其进行修改:

void append(node_t **headp, int data) { ...

或者将可能修改的头节点返回给调用方,调用方将其存储回自己的变量:

node_t *append(node_t *head, int data) { ...

在这两种情况下,建议向调用方发出内存分配失败的信号。在第一种方法中返回错误代码很容易,而在第二种方法中返回空指针可以工作,只要调用方不将返回值直接存储到其head变量中,因为在失败的情况下,以前的值将丢失。

这是使用第一种方法的修改版本:

#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int data;
node_t *next;
};
// append a new node to the list, return 0 for success, -1 for allocation failure
int append(node_t **headp, int data) {
node_t *node = (node_t *)malloc(sizeof(node_t *));
if (node == NULL)
return -1;
node->data = data;
node->next = NULL;
if (*headp == NULL) {
*headp = node;
} else {
node_t *current = *headp;
while (current->next != NULL) {
current = current->next;
}
current->next = node;
}
return 0;
}
int main(void) {
node_t *head = NULL;
if (append(&head, 4) || append(&head, 6))
printf("node allocation errorn");
printList(head);
// should free the list
return 0;
}

相关内容

  • 没有找到相关文章

最新更新