【问题标题】:C: How pointers change address in memory and what does it implyC:指针如何改变内存中的地址以及它意味着什么
【发布时间】: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 之后,headnew 的地址相同。鉴于此,我有两个问题。

首先,我是否理解正确,在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 访问的是我指向的内存区域的地址,&amp;head 访问的是指针本身的地址。但是为什么&amp;head-&gt;value 我访问的和head 一样呢?

【问题讨论】:

  • &amp;head-&gt;value&amp;(head-&gt;value),是head-&gt;value的地址,不是head
  • 继续阅读operator precedence in C
  • 好的,谢谢,现在说得通了。那么问题的第一部分呢?
  • 链表不占用“内存区域”。每个节点自己占据它自己的“区域”,因此整个列表是一个小区域链,每个区域都独立存在。指针正是这个词所说的——它指向。所以 head = new 使 head 指向同一个地方 new 点。 new 在这个意义上不是“在内存中”。 new 指向您从 malloc 获得的内存“区域”。现在head 也指向那里。如果你打印指针,你会得到一个内存单元的数字地址。这就是指针的真正含义——一个整数值。你可以认为它是一个内存单元的id
  • 这澄清了很多事情,尤其是“链表不占用“内存区域”。每个节点自己占据它自己的“区域”,因此整个列表是一个小区域链。谢谢

标签: c pointers memory struct


【解决方案1】:

首先,我是否理解正确,在head = new 之后发生的事情是,我们已经将指向链表使用的内存区域开始的指针(即从head)移动到内存中的新位置(即new 在内存中的位置)?否则(或者从技术上讲,解释清楚)发生了什么?

head = new 不动head。它改变了head 的值。 head 是一个指针;它的值是一个内存地址。

但是为什么&amp;head-&gt;value 访问的和head 一样呢?

使用 C 的语法,&amp;head-&gt;value&amp;(head-&gt;value),而不是 (&amp;head)-&gt;value。它使用head 定位head-&gt;value,然后获取它的地址。它不会取head的地址,然后将其用作指向结构的指针。

【讨论】:

  • 谢谢,我现在明白了。对问题的第一部分还有什么见解吗?
猜你喜欢
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 2010-09-14
  • 2018-03-02
相关资源
最近更新 更多