关于C指针的一个技巧问题。阅读下面的代码片段并尝试解释列表值更改的原因(此问题基于 this 代码):
tail有list的内存地址。
如何更改下面的列表?
typedef struct _node {
struct _node *next;
int value;
}Node;
int main(){
Node *list, *node, *tail;
int i = 100;
list = NULL;
printf("\nFirst . LIST value = %d", list);
tail =(Node *) &list;
node = malloc (sizeof (Node));
node->next = NULL;
node->value = i;
//tail in this point contains the memory address of list
tail->next = node;
printf("\nFinally. LIST value = %d", list);
printf("\nLIST->value = %d", (list->value));
return 0;
}
----输出
block 引用>First . List value = 0
为什么这个值???我没想到这个......
block 引用>Finally . LIST value = 16909060
LIST->value = 100
最佳答案
让我们看看程序中的内存发生了什么。您从 3 个局部变量开始,所有变量都是 Node*
类型。目前它们都指向垃圾,因为它们已被声明但尚未初始化。
内存的 ASCII 艺术图可能是(布局取决于实现)
list node tail
--------------------------
... | 0xFE | 0x34 | 0xA3 | ...
--------------------------
然后,您将 list 设置为 NULL,并将 tail
设置为节点的地址(抛弃它的类型,这是一个坏主意),给您
list node tail
--------------------------
... | NULL | 0xFE | &list | ...
--------------------------
^ |
+-------------+
然后您 malloc 一个新的 Node
,并将 list 设置为其地址。
list node tail next value
--------------------------- ------------------
... | NULL | &next | &list | ... | NULL | 100 | ...
--------------------------- ------------------
^ | | ^
| +---------------------+
+--------------+
接下来尝试将 tail->next
设置为节点。您已经说过,当您进行类型转换时,您知道 tail
指向 Node
,因此编译器相信您。 Node
尾部指向从 list
的地址开始,如下所示
tail list
next value next value
---------------------------------- ------------------
... | NULL | &list->next | &list | ... | NULL | 100 | ...
---------------------------------- ------------------
然后将 tail->next
设置为 node
,使 list
和 node
都指向 列表
结构。
list node tail next value
--------------------------- ------------------
... | &next | &next | &list | ... | NULL | 100 | ...
--------------------------- ------------------
| ^ | | ^
| | +---------------------|
| +-------------+ |
+-----------------------------+
您已将 list
打印为有符号整数(“%d”)。这是一个坏主意 - 如果您使用 64 位机器并且 printf 语句中有其他参数,它们可能会被破坏,请改用指针格式(“%p”)。 list->value
与 node->value
相同,因此它仍然是 100
。
如果您考虑一下指针在机器中的实际表示方式,那么指针就会变得更容易 - 作为一个包含所有数据(模指针大小、虚拟内存等)的巨大数组的索引。
下次使用list = node
可能会更容易。
关于c++ - 指针(技巧): Memory Reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3658420/