[英]Pointer to beginning of linked list
我在學習指針時正在練習鏈表結構,並且在列表中附加項目時遇到問題。 這是我的代碼
#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;
時,我的代碼會中斷head = node;
它不會改變main
中head
值。 我想我錯過了一些東西,但不確定是什么。 先感謝您
您正在函數 append 中按值傳遞指針頭。 因此該函數處理傳遞給它的指針的副本。 更改副本不會影響原始指針。 通過引用傳遞它或從函數返回更新的頭部。
第一種方法要好得多。
該函數可以如下所示
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
問題似乎是您通過 value傳遞head
指針,因此當您在append()
內更改它時,您只更改該函數中的局部變量 - 而不是main()
內的head
變量。
這可能有點令人困惑——如果你傳遞一個指針,你怎么能按值傳遞呢? 好吧,你可能想看看這個問題:
...最重要的是append()
需要一個node_t** head
,您將從 main 中使用append(&head, 4);
調用它append(&head, 4);
. 看到它在 Coliru 上工作。
您還為每個節點分配sizeof(node_t*)
。 您應該分配sizeof(node_t)
。
您按值傳遞列表的頭部,因此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 error\n");
printList(head);
// should free the list
return 0;
}
它不會改變 main 中 head 的值
也不應該! 如果在調用append()
時 main 中的head
值發生了變化,那么您對printList()
調用只會打印列表中的最后一個節點,而您將無法引用列表中的其他節點。
在其他答案中已經很好地解釋了head
沒有改變的原因,即您正在按值傳遞 head 指針。 要明白,這是重要的head
中main()
和head
參數append()
是完全不同的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.