簡體   English   中英

指向鏈表開頭的指針

[英]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; 它不會改變mainhead值。 我想我錯過了一些東西,但不確定是什么。 先感謝您

您正在函數 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變量。

這可能有點令人困惑——如果你傳遞一個指針,你怎么能按值傳遞呢? 好吧,你可能想看看這個問題:

在 C++ 中傳遞指針參數,按值傳遞嗎?

...最重要的是append()需要一個node_t** head ,您將從 main 中使用append(&head, 4);調用它append(&head, 4); . 看到它在 Coliru 上工作

您還為每個節點分配sizeof(node_t*) 您應該分配sizeof(node_t)

您按值傳遞列表的頭部,因此append函數無法更新調用者空間中的指針,該指針恰好具有相同的名稱head appendhead參數是與mainhead局部變量不同的變量。

您應該傳遞一個指向頭節點的指針,以便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 指針。 要明白,這是重要的headmain()head參數append()是完全不同的變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM