指向不同内存位置但更新相同变量的指针
Go Pointers pointing to different memory locations but updating same variable
总结: a
指向分配给 b
的内存地址 0x40e020
。 c
,然后分配给 b
的内存位置(或者我认为)。当我打印出 c &c
的地址时,它指向内存中的另一个位置 0x40c138
.
package main
import (
"fmt"
)
func main() {
var a int = 42
b := &a
c := b
*c = 4
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
}
问题:指针c
如何更新a
的值?我希望 a
打印出 42,但编译器吐出 4.
c 打印 a 的内存地址。 b 是保存 a 的内存地址的变量,c 是 b(这些变量保存相同的值)。
当您打印 &c 时,您打印的是保存 a 的内存地址的变量 c 的内存地址。
您可以使用 c 更新 a 的值的原因是因为 * 运算符允许您访问或跟踪 c 保存的内存地址并更新它保存的值。
让我们详细分析一下这里发生的事情:
var a int = 42
b := &a
c := b
您现在拥有三个变量,每个变量在内存中都有自己的位置。 a
是一个整数,值为 42
。 b
和c
的值相同,都是a
的内存地址。
*c = 4
这将取消引用指针 c
并将值 4
写入它指向的内存位置,即 a
的内存位置。这就是为什么在打印 a
时您会看到值 4
- 此行会覆盖 a
的内存位置中的值。这是指针的主要目的 - 允许多次引用内存中的相同值。
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
这会打印出a
的值,b
的值(即a
的地址),以及c
的地址。
一张图片可能会有所帮助。这是您计算机中的(部分)内存,从 0x40c138 到 0x40e020 左右:
+---------+ +---------+
????????: | * | (variable "b") 0x40c138: | * | (variable "c")
+----|----+ +----|----+
v ________________________________/
+---------+'
0x40e020: | 4 | (variable "a")
+---------+
变量b
和c
都指向变量a
。您打印变量 b
的 value,即 0x40e020,这是我们知道 a
本身在内存中的位置的方式。您打印变量 c
的 地址 ,这就是我们知道 c
本身在内存中的位置的方式。你没有打印变量 b
的地址,所以我们不确定它在哪里,但我们知道 b
和 c
都指向 a
,所以我们可以画出每个箭头出来的箭头。
由于从 c
出来的箭头指向 a
,因此通过 *c
写入会写入 a
。
总结: a
指向分配给 b
的内存地址 0x40e020
。 c
,然后分配给 b
的内存位置(或者我认为)。当我打印出 c &c
的地址时,它指向内存中的另一个位置 0x40c138
.
package main
import (
"fmt"
)
func main() {
var a int = 42
b := &a
c := b
*c = 4
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
}
问题:指针c
如何更新a
的值?我希望 a
打印出 42,但编译器吐出 4.
c 打印 a 的内存地址。 b 是保存 a 的内存地址的变量,c 是 b(这些变量保存相同的值)。 当您打印 &c 时,您打印的是保存 a 的内存地址的变量 c 的内存地址。 您可以使用 c 更新 a 的值的原因是因为 * 运算符允许您访问或跟踪 c 保存的内存地址并更新它保存的值。
让我们详细分析一下这里发生的事情:
var a int = 42
b := &a
c := b
您现在拥有三个变量,每个变量在内存中都有自己的位置。 a
是一个整数,值为 42
。 b
和c
的值相同,都是a
的内存地址。
*c = 4
这将取消引用指针 c
并将值 4
写入它指向的内存位置,即 a
的内存位置。这就是为什么在打印 a
时您会看到值 4
- 此行会覆盖 a
的内存位置中的值。这是指针的主要目的 - 允许多次引用内存中的相同值。
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
这会打印出a
的值,b
的值(即a
的地址),以及c
的地址。
一张图片可能会有所帮助。这是您计算机中的(部分)内存,从 0x40c138 到 0x40e020 左右:
+---------+ +---------+
????????: | * | (variable "b") 0x40c138: | * | (variable "c")
+----|----+ +----|----+
v ________________________________/
+---------+'
0x40e020: | 4 | (variable "a")
+---------+
变量b
和c
都指向变量a
。您打印变量 b
的 value,即 0x40e020,这是我们知道 a
本身在内存中的位置的方式。您打印变量 c
的 地址 ,这就是我们知道 c
本身在内存中的位置的方式。你没有打印变量 b
的地址,所以我们不确定它在哪里,但我们知道 b
和 c
都指向 a
,所以我们可以画出每个箭头出来的箭头。
由于从 c
出来的箭头指向 a
,因此通过 *c
写入会写入 a
。