【发布时间】:2021-01-05 12:20:54
【问题描述】:
我有这个node.c的简单代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int x;
struct Node *next;
} Node;
void unshift(Node **root, int value)
{
Node *newNode = malloc(sizeof(Node));
newNode->x = value;
newNode->next = *root;
*root = newNode;
}
//doesn't work if address of pointer is passed to unshift()
void foo(Node *root)
{
if (root == NULL)
{
//pass address of pointer
unshift(&root, 4);
}
}
//works with double pointer passed to unshift()
void bar(Node **root)
{
if (*root == NULL)
{
//pass double pointer
unshift(root, 4);
}
}
int main()
{
Node *root = NULL;
//works
// bar(&root);
// printf("%p\n", root);
//does not work
foo(root);
printf("%p\n", root);
}
现在有一个函数insert(Node **root, int value),它使用指向根的双指针来更改它(新创建的节点本身将成为根)。所以很明显我可以通过类型Node ** 任何一种方式-> 双指针,或指针地址。我在 2 个单独的函数中这样做 -> foo(Node*) 和 bar(Node**)。因此,在 foo 中,我传递了参数的地址,而在 bar 中,我只是传递了它的参数。
问题是,只有带有双指针的bar() 实际上会更改 main 的根指针。 foo() 函数不会,即使传递了正确的数据类型。也就是说,在用foo() 调用之后,指针根是nil(在声明中仍然是空指针),而在bar() 之后,指针实际上是changed。那么为什么编译器会以不同的方式处理地址和指针,即使它们都传递相同的数据呢?而为什么foo() 也不改变根指针呢?
【问题讨论】:
-
指针的地址就是指针所在的位置。双指针是一个包含双精度地址的变量。
-
OT:关于:
printf("%p\n", root);输出说明符%p需要void*而不是struct Node *的参数,因此语句应为:printf("%p\n", (void*)root);
标签: c pointers linked-list