C中链表上的双指针

时间:2018-06-09 07:21:44

标签: c pointers linked-list

在一个简单的链表中,为什么在插入节点时传递双指针?与第二个代码有什么区别?

void push(struct node **headRef, int data);
void push(struct node *head, int data);

2 个答案:

答案 0 :(得分:1)

在第一种情况下,您指向对head节点的引用,而在第二种情况下,您指向对链接列表的第一个节点的引用。

概略地:

// Original List structure
head -> first node -> second node

// first case
void push(struct node **headRef, int data);

head -> first node -> second node
 ^
 |
headRef

--------------------------------------
// second case
void push(struct node *headRef, int data);

head -> first node -> second node
            ^
            |
        headRef

你喜欢一个吗?这取决于。

如果您希望能够修改头节点的值,那么您应该使用双指针,否则只需使用案例2.

您还应该看一下:What is the reason for using a double pointer when adding a node in a linked list?

答案 1 :(得分:1)

C函数调用总是传递参数的。当您进入该函数时,您有一个复制来自调用者的值放在新变量中。

您可以在函数内更改这些副本的值,但调用者具有的值将保持不变。

示例:

void foo(int n)
{
    n = 1;
    printf("In foo: %d\n", n);  // Will print 1
}

void bar()
{
     int n = 42;
     printf("In bar: %d\n", n);  // Will print 42
     foo(n);
     printf("Back in bar: %d\n", n);  // Will still print 42
}

正如您所看到的,nfoo所做的更改并未在n内更改bar

那么如果您真的希望n内的bar更改呢?

您不是通过n传递指针n

像:

void foo(int *n)  // Note the *
{
    *n = 1;
    printf("In foo: %d\n", *n);  // Will print 1
}

void bar()
{
     int n = 42;
     printf("In bar: %d\n", n);  // Will print 42
     foo(&n);                    // Note the & to get a pointer to n
     printf("Back in bar: %d\n", n);  // Will now print 1
}

这也是您的代码行之间的区别:

void pushA(struct node **headRef, int data);
void pushB(struct node *head, int data);

struct node *head = NULL;
pushA(&head, 42);   // head may be changed after this call
pushB(head, 42);    // head is unchanged after this call

第一个版本可能就是您想要的,即在将新元素推送到列表时,您希望在前面插入元素,因此需要更改head的值。

另一种方法是让函数返回指向新头的指针:

struct node* push(struct node *head, int data);

struct node *head = NULL;
head = push(head, 42);