package main
import ("fmt")
func main() {
x, y := 1, 2
fmt.Printf("x 替换前的地址 =%p\n",&x)
fmt.Printf("y 替换前的地址 =%p\n",&y)
swap(&x, &y)
fmt.Println(x, y)
fmt.Printf("x 替换后的地址 =%p\n",&x)
fmt.Printf("y 替换后的地址 =%p\n",&y)
}
func swap(a, b *int) {fmt.Printf("a 变量自身的地址 =%p\n", &a)
fmt.Printf("b 变量自身的地址 =%p\n", &b)
fmt.Printf("a 替换前的 x 赋予的地址 =%p\n", a)
fmt.Printf("b 替换前的 y 赋予的地址 =%p\n", b)
fmt.Printf("a 替换前的值 =%d\n", *a)
fmt.Printf("b 替换前的值 =%d\n", *b)
*b, *a = *a, *b
fmt.Printf("a 变量自身的地址 =%p\n", &a)
fmt.Printf("b 变量自身的地址 =%p\n", &b)
fmt.Printf("a 替换后的 x 赋予的地址 =%p\n", a)
fmt.Printf("b 替换后的 y 赋予的地址 =%p\n", b)
fmt.Printf("a 替换后的值 =%d\n", *a)
fmt.Printf("b 替换后的值 =%d\n", *b)
}
输入后果如下:
x 替换前的地址 =0xc0000a0068
y 替换前的地址 =0xc0000a0080
a 变量自身的地址 =0xc0000ca020
b 变量自身的地址 =0xc0000ca028
a 替换前的 x 赋予的地址 =0xc0000a0068
b 替换前的 y 赋予的地址 =0xc0000a0080
a 替换前的值 =1
b 替换前的值 =2
a 变量自身的地址 =0xc0000ca020
b 变量自身的地址 =0xc0000ca028
a 替换后的 x 赋予的地址 =0xc0000a0068
b 替换后的 y 赋予的地址 =0xc0000a0080
a 替换后的值 =2
b 替换后的值 =1
2 1
x 替换后的地址 =0xc0000a0068
y 替换后的地址 =0xc0000a0080
替换胜利。
上面将 swap 办法中的 *b, *a = *a, *b
改为 b, a = a, b
输入后果如下:
x 替换前的地址 =0xc00000a0c0
y 替换前的地址 =0xc00000a0c8
a 变量自身的地址 =0xc000006030
b 变量自身的地址 =0xc000006038
a 替换前的 x 赋予的地址 =0xc00000a0c0
b 替换前的 y 赋予的地址 =0xc00000a0c8
a 替换前的值 =1
b 替换前的值 =2
a 变量自身的地址 =0xc000006030
b 变量自身的地址 =0xc000006038
a 替换后的 x 赋予的地址 =0xc00000a0c8
b 替换后的 y 赋予的地址 =0xc00000a0c0
a 替换后的值 =2
b 替换后的值 =1
1 2
x 替换后的地址 =0xc00000a0c0
y 替换后的地址 =0xc00000a0c8
替换失败。
内存图解析
咱们先看 b,a=a,b 这种状况
从第二种后果打印咱们晓得,a,b 本人自身也有地址,区别在于他们的地址指向的值是 x,y 的地址,所以 b,a=a,b 这种相当于把内存这一列的值进行对调(也就是 0xc00000a0c0 和 0xc00000a0c8 对调一下),然而 ab 自身地址没有扭转,因为内存的地址值变了,所以 ab 的值所指向的值也对调了(也就是a, b 的值对调了),从图上来说,ab 与 xy 没有关系
咱们再看b,a=a, b 这种状况
咱们先看一个知识点:
a = b 这句话的含意:操作符作为右值时,意义是取指针的值,作为左值时,也就是放在赋值操作符的右边时,示意 a 指针指向的变量。其实归纳起来,操作符的基本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值,当操作在左值时,就是将值设置给指向的变量。
简略来说就是:取 b 指针的值(这里值为 2), 赋给 a 指针指向的变量,a 指针指向的变量就是 x 呀,所以相当于把 2 赋给 x 同理b = a 也是这个情理
作者:蓝色记忆
链接:https://juejin.cn/post/684490…
起源:稀土掘金
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。