C 中链表上的双指针



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

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

C 函数调用始终传递参数的值。当您在函数内部时,您将调用方的值的副本放置在新变量中。

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

例:

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

如您所见,对foo内部n所做的更改不会更改nbar内部。

那么,如果你真的想改变bar内部n呢?

这就是您传递n传递指向n的指针的地方。

喜欢:

void foo(int *n)  // Note the *
{
*n = 1;
printf("In foo: %dn", *n);  // Will print 1
}
void bar()
{
int n = 42;
printf("In bar: %dn", n);  // Will print 42
foo(&n);                    // Note the & to get a pointer to n
printf("Back in bar: %dn", 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);

在第一种情况下,您指向对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。

您还应该看看这里:在链表中添加节点时使用双指针的原因是什么?

相关内容

  • 没有找到相关文章

最新更新