C 为什么可以';我们是否在单链表中的append/insert函数的函数参数中使用单个指针?

C 为什么可以';我们是否在单链表中的append/insert函数的函数参数中使用单个指针?,c,pointers,data-structures,pass-by-reference,singly-linked-list,C,Pointers,Data Structures,Pass By Reference,Singly Linked List,所以我一直在学习C中使用指针的数据结构,我怀疑为什么我们使用双指针作为函数参数,为什么我们不能在单链表的append函数中使用单个指针?(还是初学者) 在函数中,您试图更改指向列表头节点的指针 如果函数将接受第二个函数定义中的按值指针,那么函数将处理指向head节点的原始指针值的副本。更改副本不会影响原始指针。原始指针将保持不变 您可以想象(第二个)函数定义及其调用的方式如下 struct node *head; head=NULL; insert( head, 10 ); //... vo

所以我一直在学习C中使用指针的数据结构,我怀疑为什么我们使用双指针作为函数参数,为什么我们不能在单链表的append函数中使用单个指针?(还是初学者)


在函数中,您试图更改指向列表头节点的指针

如果函数将接受第二个函数定义中的按值指针,那么函数将处理指向head节点的原始指针值的副本。更改副本不会影响原始指针。原始指针将保持不变

您可以想象(第二个)函数定义及其调用的方式如下

struct node *head;
head=NULL;

insert( head, 10 );
//...

void insert( /*struct node *q,int value */ )
{
    struct node *q = head;
    int value = 10;
    //.. 
如您所见,函数处理其自身的局部变量
q
(函数参数是函数局部变量),该变量具有main中定义的指针
头的值副本。因此,在函数中,局部变量
q
获得一个新值。指针头的值未被更改

因此,您需要通过引用传递指针。在C语言中,通过引用传递对象意味着传递一个指向对象的指针,而对象是使用指针间接传递给函数的

但无论如何,函数定义都是错误的。当内存分配失败时,它可以定义得更简单,并且没有未定义的行为。比如说

int insert( struct node **head, int value )
{
    struct node *new_node = malloc( sizeof( struct node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->number = value;
        new_node->next   = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = new_node;
    }

    return success;
}
如果不通过引用将指针传递到head节点,则需要从函数返回指针的新值。在这种情况下,函数可以如下所示

struct node * insert( struct node *q, int value )
{
    struct node *new_node = malloc( sizeof( struct node ) );

    if ( new_node != NULL )
    {
        new_node->number = value;
        new_node->next   = NULL;

        if ( q == NULL )
        {
            q = new_node;
        }
        else
        {
            struct node *current = q;
            while ( current->next != NULL ) current = current->next;
            current->next = new_node;
        }
    }

    return q;
}
在这种情况下,当列表为空时,必须按照以下方式第一次调用函数

head = insert( head, 10 );

在函数中,您试图更改指向列表头节点的指针

如果函数将接受第二个函数定义中的按值指针,那么函数将处理指向head节点的原始指针值的副本。更改副本不会影响原始指针。原始指针将保持不变

您可以想象(第二个)函数定义及其调用的方式如下

struct node *head;
head=NULL;

insert( head, 10 );
//...

void insert( /*struct node *q,int value */ )
{
    struct node *q = head;
    int value = 10;
    //.. 
如您所见,函数处理其自身的局部变量
q
(函数参数是函数局部变量),该变量具有main中定义的指针
头的值副本。因此,在函数中,局部变量
q
获得一个新值。指针头的值未被更改

因此,您需要通过引用传递指针。在C语言中,通过引用传递对象意味着传递一个指向对象的指针,而对象是使用指针间接传递给函数的

但无论如何,函数定义都是错误的。当内存分配失败时,它可以定义得更简单,并且没有未定义的行为。比如说

int insert( struct node **head, int value )
{
    struct node *new_node = malloc( sizeof( struct node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->number = value;
        new_node->next   = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = new_node;
    }

    return success;
}
如果不通过引用将指针传递到head节点,则需要从函数返回指针的新值。在这种情况下,函数可以如下所示

struct node * insert( struct node *q, int value )
{
    struct node *new_node = malloc( sizeof( struct node ) );

    if ( new_node != NULL )
    {
        new_node->number = value;
        new_node->next   = NULL;

        if ( q == NULL )
        {
            q = new_node;
        }
        else
        {
            struct node *current = q;
            while ( current->next != NULL ) current = current->next;
            current->next = new_node;
        }
    }

    return q;
}
在这种情况下,当列表为空时,必须按照以下方式第一次调用函数

head = insert( head, 10 );