鉴于以下结构:
struct node
{
int data;
struct node *next;
};
以下两个功能有什么区别:
void traverse(struct node *q);
和
void traverse(struct node **q);
如何使用它们?
答案 0 :(得分:5)
一个采用指向节点的指针:
void traverse(struct node *q);
另一个指向节点的指针(注意函数的名称更改)。
void insert(struct node **q);
当您需要访问指向的内容时,将使用前者。当您需要使用 I.e.访问指向的内容时,将使用后者。您可能需要将来自调用方的实际指针变量修改为和 out参数。
前者的一个很好的例子是走链接列表的枚举。你没有修改列表头,你只需要一个指向开始节点的指针。
后者的一个很好的例子是当你将一个节点推入一个堆栈时,列表头指针本身将在完成该功能之前被改变。
与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
答案 1 :(得分:2)
第一个是单个指针。它可以修改数据和下一个,但不能修改传递给函数的参数。这通常在已为结构分配空间时使用。
q->data = 4; /* works */
q = malloc(sizeof(struct node)); /* new memory CANNOT be seen outside the function */
第二个是双指针,所以你不仅可以修改字段数据和下一个,但你也可以为它设置malloc空间,并在函数外部看到新空间。
(*q)->data = 4; /* works */
*q = malloc(sizeof(struct node)); /* new memory CAN be seen outside the function */
答案 2 :(得分:1)
struct node *q
表示变量q是指向节点的指针。
struct node **q
表示变量q是指向节点的指针。
struct node theNode;
struct node *p1 = &theNode;
struct node **p2 = &p1;
答案 3 :(得分:0)
这类似于passing by value and passing by reference之间的差异。
这里传递struct node *q
可以修改q指向并使输入指针指向的内容生效的内容,而不是指针本身。所以它类似于passing by value
,其中q是类型struct node *
虽然通过struct node **q
可能会改变所有内容,包括输入指针(可能是struct node * p;和pass&amp; p)的值和地址,并导致p。