C 指向链接列表开头的指针

C 指向链接列表开头的指针,c,struct,linked-list,append,singly-linked-list,C,Struct,Linked List,Append,Singly 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 =

我在学习指针时练习链表结构,在列表中添加项目时遇到问题。这是我的密码

#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;
}
#包括
#包括
类型定义结构节点;
结构节点{
int数据;
节点_t*下一步;
};
void append(节点头,int数据){
if(head==NULL){
node_t*node=(node_t*)malloc(sizeof(node_t*));
节点->数据=数据;
节点->下一步=空;
头部=节点;
}否则{
node_t*node=(node_t*)malloc(sizeof(node_t*));
节点->数据=数据;
节点->下一步=空;
if(head->next==NULL){
head->next=节点;
}否则{
节点_t*电流=头部;
而(1){
如果(当前->下一步==NULL){
当前->下一步=节点;
打破
}
当前=当前->下一步;
}
}
}
}
内部主(空){
节点头=空;
附加(头,4);
附加(头,6);
印刷品清单(标题);
返回0;
}
当我执行
head=node时,我的代码中断
它不会更改
main
head
的值。我想我遗漏了什么,但不确定是什么。
提前谢谢

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

这可能有点让人困惑——如果传递指针,如何传递值?好吧,你可能想看看这个问题:

。。。底线是
append()
需要获取一个
节点\u t**head
,您将使用
append(&head,4)从main调用它。看到了


另外,您正在为每个节点分配
sizeof(node\u t*)
。您应该分配
sizeof(node\u t)

您在函数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;
}

通过值传递列表的头,因此
append
函数无法更新调用方空间中的指针,因为调用方空间恰好具有相同的名称
head
append
中的
head
参数与
main
中的
head
局部变量是一个单独的变量

您应该将指针传递给head节点,以便
append
可以修改它:

void append(node_t **headp, int data) { ...
或者将可能修改的head节点返回给调用者,调用者将把它存储回自己的变量:

node_t *append(node_t *head, int data) { ...
在这两种情况下,建议向调用者发出内存分配失败的信号。在第一种方法中返回错误代码很容易,而在第二种方法中返回空指针可以工作,只要调用方不将返回值直接存储到其
变量中,就像在失败的情况下,先前的值将丢失一样

以下是第一种方法的修改版本:

#包括
#包括
类型定义结构节点;
结构节点{
int数据;
节点_t*下一步;
};
//将新节点追加到列表中,返回0表示成功,返回1表示分配失败
int append(节点**headp,int数据){
node_t*node=(node_t*)malloc(sizeof(node_t*));
if(node==NULL)
返回-1;
节点->数据=数据;
节点->下一步=空;
如果(*headp==NULL){
*headp=节点;
}否则{
node_t*current=*headp;
while(当前->下一步!=NULL){
当前=当前->下一步;
}
当前->下一步=节点;
}
返回0;
}
内部主(空){
节点头=空;
if(追加(&head,4)| |追加(&head,6))
printf(“节点分配错误\n”);
印刷品清单(标题);
//你应该释放这个列表
返回0;
}
它不会改变主回路中的水头值

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


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

请记住,在C中,函数的参数是按值传递的。这意味着该值被复制到参数变量中。修改参数变量(作为副本)不会修改原始值。请做一些关于在C中模拟传递值的研究。如果我将其设置为全局,它仍然不会改变它,但应该正确吗?@lukaa123如果您将
head
设置为全局变量,则取决于它是否被另一个同名的局部变量“隐藏”。此外,您不应该使用全局变量——这是一种错误的做法,会导致大型程序出现错误和令人头痛的问题。
node_t *append(node_t *head, int data) { ...