函数头中struct *和struct **之间的区别

时间:2019-04-10 16:07:59

标签: c struct linked-list

我正在尝试用C解决我的作业,该作业要求我创建一个函数,该函数将char值放在已排序的链表中的正确位置。 实际上,在使它成为struct typedef name *structstruct typedef name **struct之间,在函数标头中并没有真正的区别。

当我看老师的解决方案时,她是用**来做的,并不理解这个意思。

void insert_in_sorted_list(Node *lst, char x) {
    Node *temp;
    while (lst) {
        if (x > lst->value && x < lst->next->value) {
            temp = (Node*)malloc(sizeof(Node));
            temp->value = x;
            temp->next = lst->next;
            lst->next = temp;
        }
        else lst = lst->next;
    }
}

3 个答案:

答案 0 :(得分:0)

简单的思考方法是* <something>表示指向某物的指针,而'**`表示指向某物的指针。

由于c是按值传递的,所以“更改”参数的唯一方法是将指针传递给它。

所以带有**的函数将更改指针指向该函数的指针。

答案 1 :(得分:0)

  • struct-是一个占用内存的数据对象。
  • struct *-是指向该内存块的指针
  • struct **-是指向该内存块的指针! (是的,现在令人困惑)

如果将结构传递给函数,则由于每个函数都复制一个副本,因此无法更改原始数据。因此,通常您将指针传递给该结构,这意味着您所做的任何更改都将应用于原始数据。也就是说,您不更新按值副本,而是就地更新旧的内存结构。

但是,有时还没有结构(例如,因为您想在函数中构造一个结构),因此无法告诉调用方将这个新结构放在何处。因此,您必须传递一个**来说“我已经创建了这个结构,并且它在这里”,然后将该位置传递给调用方。也就是说,您指向创建该结构的内存,然后通过“指针指向”参数技巧将该位置传递回去。

您不能简单地传递一个指向该结构的指针,因为它是通过值(即复制)传递给函数的。因此,当函数退出时,将保留旧的指针值。因此是指针到指针。

指针在概念上比较笨拙,恕我直言,认为它们的最佳方法是将其作为包含内存位置(即它们实际所在的位置)的整数值,而不是尝试将它们理解为某种抽象概念。那也可以帮助我们了解性能和内存复制等很多东西。

答案 2 :(得分:0)

当您接受带有*的参数时,实际上是在接受指向某个地址的地址(这称为指针)。如果您使用**接受参数,那么您正在接受指向该指针的指针。

所以这个:

void insert_in_sorted_list(Node *lst, char x)

正在接受指向Node的指针

这:

void insert_in_sorted_list(Node **lst, char x)

正在接受指向Node的指针。

如果我们已经创建了一个列表并且没有添加到列表的前面或后面,那么您的实现将起作用。但是请考虑如果您需要更改列表中的第一项,可能会发生什么。如果用户有一个指向列表中第一个节点的指针并将其传递给函数,而新节点需要插入到第一个节点的前面,则该函数可以将其正确地插入到第一个节点的前面,但是当用户查找时使用此功能后,它们仍然在列表中具有指向同一Node的指针(不再是第一个指针),并且不知道其前面存在节点。因此,用户将需要将指向第一个节点的指针传递给指针,这样可以更改指向第一个Node的指针。

更新代码以接受指向Node的指针的指针,现在您需要使用*lst而不是lst来访问指向节点的指针

void insert_in_sorted_list(Node ** lst, char x)

要考虑的另一件事是,如果用户的列表为空,则不会插入任何内容。

考虑一下如果到达最后一个节点(即lst->next为NULL会发生什么),当我们尝试访问lst->next->value时,我们将遇到某种NULL指针异常。即使我们不这样做,该代码也不会在末尾插入另一个节点?