Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中链表上的双指针_C_Pointers_Linked List - Fatal编程技术网

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
inside
foo
所做的更改不会更改
n
inside
bar

那么,如果您真的想更改
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
inside
foo
所做的更改不会更改
n
inside
bar

那么,如果您真的想更改
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更新了我的答案。如果你插入头以外的位置,你不必通过双指针。如果你插入头以外的位置,你不必通过双指针谢谢你的解释!谢谢你的解释!