C语言中链表上的双指针
在简单的链表中,插入节点时为什么要传递双指针?第二个代码有什么区别C语言中链表上的双指针,c,pointers,linked-list,C,Pointers,Linked List,在简单的链表中,插入节点时为什么要传递双指针?第二个代码有什么区别 void push(struct node **headRef, int data); void push(struct node *head, int data); 在第一种情况下,您将引用指向head节点,而在第二种情况下,您将引用指向链表的第一个节点 图解法: // Original List structure head -> first node -> second node // first case
void push(struct node **headRef, int data);
void push(struct node *head, int data);
在第一种情况下,您将引用指向
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
你是更喜欢一个还是另一个?视情况而定
如果您希望能够修改head节点的值,那么应该使用双指针,否则就使用用例2
您还应该看看这里:在第一种情况下,您指向的是
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
你是更喜欢一个还是另一个?视情况而定
如果您希望能够修改head节点的值,那么应该使用双指针,否则就使用用例2
您还应该看看这里: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
insidefoo
所做的更改不会更改n
insidebar
那么,如果您真的想更改n
内bar
,该怎么办
在这里,您没有传递n
而是将指针传递到n
比如:
这也是代码行之间的区别:
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);
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
insidefoo
所做的更改不会更改n
insidebar
那么,如果您真的想更改n
内bar
,该怎么办
在这里,您没有传递n
而是将指针传递到n
比如:
这也是代码行之间的区别:
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);
一个比另一个有什么优势?这两种形式正确吗?@LucyFer更新了我的答案。一种形式比另一种形式有什么优势?这两种形式正确吗?@LucyFer更新了我的答案。如果你插入头以外的位置,你不必通过双指针。如果你插入头以外的位置,你不必通过双指针谢谢你的解释!谢谢你的解释!