繁体   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