C 什么';使用指针对指针有什么意义?

C 什么';使用指针对指针有什么意义?,c,pointers,linked-list,insertion,C,Pointers,Linked List,Insertion,我在一个网站上找到了这段代码,用于在列表开头的链接列表中插入节点 void push(struct Node** head_ref, int new_data) { /* 1. allocate node */ struct Node* new_node = (struct Node*) malloc(sizeof(struct Node)); /* 2. put in the data */ new_node->data = new_data; /* 3. Make next o

我在一个网站上找到了这段代码,用于在列表开头的链接列表中插入节点

void push(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));

/* 2. put in the data  */
new_node->data  = new_data;

/* 3. Make next of new node as head */
new_node->next = (*head_ref);

/* 4. move the head to point to the new node */
(*head_ref)    = new_node;
}
这是函数调用-

push(&head, 7);
我的问题是,为什么要走很长的路,传递指针的地址,然后在函数内部的地址提取值。 为什么我们不能简单地在函数中传递指针
head
,然后像这样赋值呢-

new_node->next=head_ref;

?调用程序中的变量头是指向列表头的指针。您需要一个指向此变量的指针才能在push()中更新它。因此,您可以传递一个指向保存指针的变量的指针,以便更新该变量。

调用程序中的变量头是指向列表头的指针。您需要一个指向此变量的指针才能在push()中更新它。因此,您传递一个指向保存指针的变量的指针,以便您可以更新该变量。

如果传递的是
head
而不是
&head
,则行

(*head_ref)    = new_node;
必须改为

head_ref    = new_node;
然而,这将是功能的局部变化。它不会更改调用函数中的
head
的值。这有两个问题:

  • 调用函数永远不会获得工作列表
  • 函数中分配的内存将是内存泄漏

  • 如果您通过了
    head
    而不是
    head
    ,则该行

    (*head_ref)    = new_node;
    
    必须改为

    head_ref    = new_node;
    
    然而,这将是功能的局部变化。它不会更改调用函数中的
    head
    的值。这有两个问题:

  • 调用函数永远不会获得工作列表
  • 函数中分配的内存将是内存泄漏

  • 您还可以按如下方式编写代码:

    struct Node* push(struct Node* head_ref, int new_data)
    {
        struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
        new_node->data = new_data;
        new_node->next = head_ref;
        return new_node;
    }
    
    head = push(head, 7);
    
    并称之为:

    struct Node* push(struct Node* head_ref, int new_data)
    {
        struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
        new_node->data = new_data;
        new_node->next = head_ref;
        return new_node;
    }
    
    head = push(head, 7);
    

    它实现了完全相同的功能,即在列表的开头插入一个新节点,然后更新
    head
    以指向该新节点。但在我看来,这并不是一个很好的解决方案,因为它允许push()函数的调用方忘记将返回值赋给
    head
    ,此时将出现孤立节点并最终导致内存泄漏。

    您也可以按如下方式编写代码:

    struct Node* push(struct Node* head_ref, int new_data)
    {
        struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
        new_node->data = new_data;
        new_node->next = head_ref;
        return new_node;
    }
    
    head = push(head, 7);
    
    并称之为:

    struct Node* push(struct Node* head_ref, int new_data)
    {
        struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
        new_node->data = new_data;
        new_node->next = head_ref;
        return new_node;
    }
    
    head = push(head, 7);
    

    它实现了完全相同的功能,即在列表的开头插入一个新节点,然后更新
    head
    以指向该新节点。但在我看来,这并不是一个很好的解决方案,因为它允许push()函数的调用方忘记将返回值赋给
    ,此时将出现孤立节点并最终导致内存泄漏。

    这一切都与您选择的编程风格有关。使用一组函数来操作列表可以使程序结构合理。这样可以使它更具可读性。如果需要从多个位置操作同一个列表或操作多个列表,它还可以避免剪切粘贴

    组织职能的方式由您决定。我个人喜欢你例子中的方式。在这种情况下,只需在参数中指定一次指向head的指针。如果从函数返回,则在程序中使用错误指针的风险更高

    “C”有足够的工具集来编写任何类型的程序。然而,有时您需要遵循特定的规则来应用它们,比如在您的案例中指针的地址。不太方便,但可靠且已证明有效。作为一名“C”程序员,你会很快习惯它


    你也可以查看C++,它有更好的工具使这更方便。

    < P>这都与你选择的编程风格有关。使用一组函数来操作列表可以使程序结构合理。这样可以使它更具可读性。如果需要从多个位置操作同一个列表或操作多个列表,它还可以避免剪切粘贴

    组织职能的方式由您决定。我个人喜欢你例子中的方式。在这种情况下,只需在参数中指定一次指向head的指针。如果从函数返回,则在程序中使用错误指针的风险更高

    “C”有足够的工具集来编写任何类型的程序。然而,有时您需要遵循特定的规则来应用它们,比如在您的案例中指针的地址。不太方便,但可靠且已证明有效。作为一名“C”程序员,你会很快习惯它


    你也可以查看C++,它有更好的工具使这个更方便。

    因为函数正在改变<代码>头值Ref< /C>的值。由于
    head
    具有指针类型,您需要将指针传递给
    push
    的指针,以更新
    head
    的值。读取将指针传递给int的意义是什么?嗯:也许你希望函数能够改变实际的int。顺便说一句:你不需要括号:
    new\u node->next=(*head\u ref)-->
    new\u node->next=*head\u ref。相同:
    *head\u ref=新节点因为函数也在更改
    head\u ref
    的值。由于
    head
    具有指针类型,您需要将指针传递给
    push
    的指针,以更新
    head
    的值。读取将指针传递给int的意义是什么?嗯:也许你希望函数能够改变实际的int。顺便说一句:你不需要括号:
    new\u node->next=(*head\u ref)-->
    new\u node->next=*head\u ref。相同:
    *head\u ref=新节点这也不一定是一个更糟糕的解决方案,它只是增加了分配返回的要求。通过将指针传递到指向类型的指针,您可以实现两个方面的最佳效果(例如,灵活性)。。。返回指向当前添加节点的指针(用于分配或立即使用)