【发布时间】:2021-12-19 08:48:53
【问题描述】:
这是对这个问题的跟进:Why does a function which returns void not hold value?。一位用户确实建议我在函数struct node * insert_front 中绘制指针,所以主要问题是关于该函数和这行代码head = new
这是所需的最少代码:
#include <stdio.h>
#include <stdlib.h>
struct node {
int value;
struct node* next;
};
struct node* init(int value) {
struct node* head = malloc(sizeof(struct node));
if (!head) return NULL;
head->value = value;
head->next = NULL;
return head;
}
void insert_back(struct node* head, int value) {
if (!head) return;
struct node* temp = head;
struct node* new = malloc(sizeof(struct node));
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = new;
new->value = value;
new->next = NULL;
return;
}
struct node* insert_front(struct node* head, int value) {
struct node* new = (struct node*)malloc(sizeof(struct node));
new->value = value;
new->next = head;
printf("head->value: %d\n", head->value);
printf("head->value ptr: %p\n", &head->value);
printf("new->value: %d\n", new->value);
printf("new->value ptr: %p\n", &new->value);
head = new;
printf("head->value: %d\n", head->value);
printf("head->value ptr: %p\n", &head->value);
printf("new->value: %d\n", new->value);
printf("new->value ptr: %p\n", &new->value);
return new;
}
int main() {
struct node* head = init(5);
insert_back(head, 7);
insert_back(head, 9);
insert_back(head, 12);
head = insert_front(head, 999)
return 1;
}
struct node* insert front(...) 产生的输出是
// after, new->next = head
head->value: 5
head->value ptr: 0x(...)9e0
new->value: 999
new->value ptr: 0x(...)a50
// after, head = new
head->value: 999
head->value ptr: 0x(...)a50
new->value: 999
new->value ptr: 0x(...)a50
所以我们看到在head = new 之后,head 和new 的地址相同。鉴于此,我有两个问题。
首先,我是否理解正确,在head = new 之后发生的事情是,我们已将指向链表使用的内存区域开始的指针(即从head)移动到内存中的新位置(即new 在内存中的位置)?否则(或者从技术上讲,解释清楚)发生了什么?
其次,当我打印时:
printf("&head->value: %p\n", &head->value);
printf("&head: %p\n", &head);
printf("head: %p\n", head);
我得到
&head->value: 0x(...)9e0
&head: 0x(...)8c8
head: 0x(...)9e0
所以,head 访问的是我指向的内存区域的地址,&head 访问的是指针本身的地址。但是为什么&head->value 我访问的和head 一样呢?
【问题讨论】:
-
&head->value是&(head->value),是head->value的地址,不是head。 -
好的,谢谢,现在说得通了。那么问题的第一部分呢?
-
链表不占用“内存区域”。每个节点自己占据它自己的“区域”,因此整个列表是一个小区域链,每个区域都独立存在。指针正是这个词所说的——它指向。所以
head = new使head指向同一个地方new点。new在这个意义上不是“在内存中”。new指向您从malloc获得的内存“区域”。现在head也指向那里。如果你打印指针,你会得到一个内存单元的数字地址。这就是指针的真正含义——一个整数值。你可以认为它是一个内存单元的id。 -
这澄清了很多事情,尤其是“链表不占用“内存区域”。每个节点自己占据它自己的“区域”,因此整个列表是一个小区域链。谢谢