在一个简单的链表中,为什么在插入节点时传递双指针?与第二个代码有什么区别?
void push(struct node **headRef, int data);
void push(struct node *head, int data);
答案 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
}
正如您所看到的,n
内foo
所做的更改并未在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);