C语言 链表中指针指针的奇怪行为



让我们考虑以下代码:

#include <stdio.h>
#include <stdlib.h>
struct NODE {
int value;
struct NODE *next;
};
int prepend(struct NODE **head, int n){
struct NODE *new_node = (struct NODE *)malloc(sizeof(struct NODE));
if (!new_node) return -1;
new_node->value = n;
new_node->next = *head;
*head = new_node;
return 0;
}   
void pointer_address(struct NODE *head) {
struct NODE **p_current = &head;
struct NODE *next = NULL;
while (*p_current) {
printf("%pn", (*p_current));        
next = (**p_current).next;
printf("%pnn", (*p_current));
p_current = &(next);
}
}
void delete_list(struct NODE *head) {
struct NODE *current = head;
struct NODE *next = NULL;
while (current) {
next = current->next;
free(current);
current = next;
}
}
int main() {
struct NODE *head = NULL;
for(size_t i = 1; i < 10; i++) {
if (prepend(&head, i)) {
perror("Somenthing went wrong!n");
return -1;
}
}
pointer_address(head);
delete_list(head);
}

在实践中,我创建了一个链表,并在其中预置了一些整数值。但是我无法理解的是函数"pointer_address"的输出。特别是我得到

0x55871ac39360
0x55871ac39360
0x55871ac39340
0x55871ac39320
0x55871ac39320
0x55871ac39300
0x55871ac39300
0x55871ac392e0
0x55871ac392e0
0x55871ac392c0
0x55871ac392c0
0x55871ac392a0
0x55871ac392a0
0x55871ac39280
0x55871ac39280
0x55871ac39260
0x55871ac39260
(nil)

当然,每次运行程序时,特定值都是不同的。然而,我真正无法理解的是,为什么从第二行开始,每对夫妇的印刷值都不同。它们是

printf("%pn", (*p_current)); 

在这两种情况下。此外,我注意到,从第三行开始,上面的一行等于前几行的最后一行。

问题

这是怎么回事?

免責聲明

我知道这段代码没有做任何有趣的事情,同样的事情可以用其他方式完成。但是,我的兴趣是了解我的代码发生了什么。

您的pointer_address函数:

void pointer_address(struct NODE *head) {
struct NODE **p_current = &head;
struct NODE *next = NULL;
while (*p_current) {
printf("%pn", (*p_current));        
next = (**p_current).next;
printf("%pnn", (*p_current));
p_current = &(next);
}
}

产生奇怪结果的行是:

p_current = &(next);

这意味着当您更改next的值时,*p_current的值也会更改,因为它们引用相同的内存。因此,printf语句之间的行会更改*p_current的值:

next = (**p_current).next;

这个函数的更明智的实现不会使用指向指针的指针,只需要一个指针:

void pointer_address(struct NODE *head) {
struct NODE *p_current = head;
struct NODE *next = NULL;
while (p_current) {
printf("%pn", p_current);        
next = p_current->next;
printf("%pnn", p_current);
p_current = next;
}
}

或者进一步简化:

void pointer_address(struct NODE *p_current) {
while (p_current) {
printf("%pn", p_current);        
p_current = p_current->next;
}
}

相关内容

  • 没有找到相关文章

最新更新