1

给定以下结构:

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

以下两个功能有什么区别:

void traverse(struct node *q);

void traverse(struct node **q);

它们是如何使用的?

4

4 回答 4

5

一个是指向节点的指针:

void traverse(struct node *q);

另一个是指向节点的指针(注意函数的名称更改)。

void insert(struct node **q);

当您需要访问指向的内容时使用前者。当您需要访问指向的内容时使用后者 -即您可能需要从调用方修改实际指针变量作为潜在的输入输出参数。

前者的一个很好的例子是遍历链表的枚举。您没有修改列表头,您只需要一个指向开始节点的指针。

后者的一个很好的例子是当你将一个节点压入堆栈时,列表头指针本身将在完成函数之前被更改。

像 C 中的所有东西(不支持数组)一样,如果您想将某些东西修改为输出参数,您需要将该参数声明为正式的指针类型并传递您正在修改的东西的地址。在后一种情况下(我认为这是造成混乱的情况),我们需要修改的是指针变量本身,因此必须将其声明为指向指针的指针,然后传入指针的地址.

例子大声说话,所以看看:

#include <stdio.h>
#include <stdlib.h>

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

void traverse(struct node* p)
{
    while (p)
    {
        printf("%d\n", p->data);
        p = p->next; // note. modifies only our local variable p.
                     // caller side uneffected.
    }
}

void insert(struct node **pp, int data)
{
    struct node *p = malloc(sizeof(*p));
    p->data = data;
    p->next = *pp;
    *pp = p; // note: save new list head here.
}

int main(int argc, char *argv[])
{
    struct node *head = NULL;
    insert(&head, 1);
    printf("head = %p\n", head);
    insert(&head, 2);
    printf("head = %p\n", head);
    insert(&head, 3);
    printf("head = %p\n", head);
    traverse(head);

    // yes, I know its leaking memory. that isn't the subject of this question.
    return 0;
}

输出

head = 0x1001000e0
head = 0x100103b40
head = 0x100103b50
3
2
1
于 2013-09-09T02:59:24.980 回答
2

第一个是单指针。它可以修改 data 和 next,但不能修改传递给函数的参数指向的内容。这通常在已经为结构分配空间时使用。

q->data = 4; /* works */
q = malloc(sizeof(struct node)); /* new memory CANNOT be seen outside the function */

第二个是双指针,因此您不仅可以修改字段 data 和 next,还可以为其分配空间并在函数外部看到新空间。

(*q)->data = 4; /* works */
*q = malloc(sizeof(struct node)); /* new memory CAN be seen outside the function */
于 2013-09-09T02:58:16.493 回答
1

struct node *q表示变量 q 是指向节点的指针。

struct node **q表示变量 q 是指向节点指针的指针。

struct node theNode;
struct node *p1 = &theNode;
struct node **p2 = &p1;
于 2013-09-09T02:57:36.927 回答
0

这类似于按值传递和按引用传递的区别。

这里传递struct node *q可以修改 q 指向的内容,对输入指针指向的内容生效,而不是指针本身。所以它类似于passing by valuewhere 和 q 是类型的值struct node *

虽然传递struct node **q可以改变一切,包括输入指针的值和地址(可能是 struct node *p; 并传递 &p),并导致 p。

于 2013-09-09T03:01:01.637 回答