6

我正在尝试对链接列表进行排序。我对何时使用struct node*head和何时使用感到困惑struct node **head,可以使用它们来完成实现。

我什么时候应该使用:

void sortedinsert(struct node **head)

我应该什么时候使用:

void sortedinsert(struct node *head)
4

10 回答 10

12

使用此函数签名:

void changeNode(struct node *head)

您有一个指向该节点的指针,因此您可以更改该结构。您无法更改变量 head指向的内容。让我们假设以下定义struct node

struct node
{
    int field1;
    struct node *next;
}

使用给定的函数签名 和struct node,考虑以下操作可以改变函数中的结构:

void changeNode(struct node *head)
{
    head->field1 = 7;
    head->next = malloc(sizeof(struct node));
}

C 是按值传递:当我们将变量传递给函数时,函数会得到一个副本。这就是为什么我们传递一个指向 a 的指针struct node,以便我们可以更改它,并在函数之外获得这些更改的效果。但是我们仍然只得到指针本身的副本。所以下面的操作没有用:

void changeNode(struct node *head)
{
    // we're only changing the copy here
    head = malloc(sizeof(struct node));
}

的更改head 不会反映在函数之外。为了改变head指向的内容,我们必须使用额外的间接级别:

void changeNode(struct node **head)
{
    // now we're changing head
    *head = malloc(sizeof(struct node));

    // alternately, we could also do this:
    *head = NULL;
}

现在对 的更改head反映在函数之外。

于 2012-08-25T17:25:39.490 回答
2

第一个是指向节点的指针,它是一个结构。

(struct node *) head;

定义head为可以存储 a 的地址的变量node

这允许node在方法中通过引用传递。

第二个是指向节点的指针,它是一个结构。

(struct node **) head;

定义head为变量,该变量可以存储另一个具有 a 的地址的变量的地址node

这允许node *在方法中通过引用传递。

于 2012-08-25T17:20:43.143 回答
2

如果 head 必须始终指向链接列表的头部(一个恒定位置),则使用 struct node* head 如果您打算更改 head 指向的位置,请使用 node **head

于 2012-08-25T17:21:53.143 回答
2

struct node **head您通过head使其可以引用/指向不同的内存区域来传递那里的指针的地址。随着struct node *head你不能修改head指向其他任何地方

于 2012-08-25T17:22:17.110 回答
1

案例1:当您使用时:

void sortedinsert(struct node **head)

在函数内部,您实际上将修改head 指针,因为很可能您将在*head内部使用。最sortedinsert有可能与参数一起调用&head

案例2:当您使用时:

void sortedinsert(struct node *head)

在函数内部,您将修改指针的副本,因为很可能您将在内部使用变量。最有可能与参数一起调用。head headsortedinserthead

于 2019-02-14T06:58:13.457 回答
0

node*是指向节点结构的指针。node**是指向节点结构的指针的指针。当您想通过引用修改指针时,在 C 中使用指向指针的指针。

假设您想在节点 B 上执行一个操作,该操作可能会用不同的节点替换节点 B。做事的一种方法是

nodeA.next = foo(nodeA.next);

另一种选择是做

foo(&nodeA.next);

并让 foo 隐式替换nodeA.next指针。

于 2012-08-25T17:21:25.507 回答
0

在这个例子中,由于 head 的值在创建时可能会改变(它可以指向与当前节点不同的其他节点),

你应该使用,

void sortedinsert(struct node **head)

因为您的头部可能需要修改。

并且下面的protoptye似乎需要更改,

void sortedinsert(struct node *head)

因为这不允许你修改头部,它应该是在这种情况下(如果你正在使用这个),

struct node * sortedinsert(struct node *head)

它返回更新的头部,可以在这个函数的调用者中使用。

于 2012-08-25T17:30:15.353 回答
0

运行或阅读这个你可以看到它

#include <stdio.h>
struct node{
    int one;
    int two;
    struct node * next;
    //char location[100];
};
void changeHead(struct node** head){

}
void sort(struct node* head){

}
int main(){
    struct node* head = (struct node*) (malloc (sizeof(struct node)));

    // now head pointing to a node stucture ( if you dereferance head you get teh first value)

    struct node* tmp = head;

    struct node** newHead = (struct node**) (malloc (sizeof(struct node*)));

    //New head points to a 'struct node*', which hold an addtess of another struct node

    head->one = 12;//*head->one =12; //head.one = 12 is wrong cos it is holding an address.
    // you can do it but it doesnt make sence since you dont know whats on address #12


    // now if you want head to point to old head which is on tmp at the moment
    *newHead = head;

    // now if you working with 2 linked list and you want to change the heads use below
    changeHead(newHead);

    // if you want to just sort its better and easy to use
    sort(head);

    //chack whats on head and newhead
    printf("double derefence newHead:%d\n",**newHead);
    printf("derefence newHead(its and address same ad address of head):%d\n",*newHead);
    printf("Head(its and address):%d\n",head);
    printf("derefence Head:%d\n",*head);//head->one works too
}
于 2012-08-25T18:17:36.423 回答
0
  1. 要更改指向第一个节点的 head ,您需要传递 head 的地址,即(&head)调用函数(因此,您在函数中声明了指向指针变量的指针,(struct node**head)因为它接收到的地址 head不过是指向第一个节点的指针。
  2. 但是,如果您知道 head 将保持固定,即您不希望 head 指向其他节点(例如..没有在开头插入新节点),那么您只能通过 (head) 调用函数并(*head)写入函数定义。
于 2015-02-24T19:55:58.270 回答
0

简而言之**head,当您想更改“head”指向的位置时使用您的,否则使用*head不允许更改位置的位置。

于 2012-08-25T19:34:01.433 回答