go里面指针符号的*和&

示例代码如下:

package main

import "fmt"

func main() {
    var a int = 1
    var b *int = &a //*b 是int型 (目前是这样理解的2019.10.16)
    var c **int = &b //**c 是int型
    var x int = *b

    fmt.Println("a = ",a)
    fmt.Println("&a = ",&a)
    fmt.Println("*&a = ",*&a)
    fmt.Println("b = ",b)
    fmt.Println("&b = ",&b)
    fmt.Println("*&b = ",*&b)
    fmt.Println("*b = ",*b)
    fmt.Println("c = ",c)
    fmt.Println("*c = ",*c)
    fmt.Println("&c = ",&c)
    fmt.Println("*&c = ",*&c)
    fmt.Println("**c = ",**c)
    fmt.Println("***&*&*&*&c = ",***&*&*&*&*&c)
    fmt.Println("x = ",x)
}

执行结果如下:


fmt.Println("a = ",a) // a =  1
fmt.Println("&a = ",&a) // &a =  0xc00000a0b8
fmt.Println("*&a = ",*&a) // *&a =  1
fmt.Println("b = ",b) // b =  0xc00000a0b8
fmt.Println("&b = ",&b) // &b =  0xc000006028
fmt.Println("*&b = ",*&b) // *&b =  0xc00000a0b8
fmt.Println("*b = ",*b) // *b =  1
fmt.Println("c = ",c) // c =  0xc000006028
fmt.Println("*c = ",*c) // *c =  0xc00000a0b8
fmt.Println("&c = ",&c) // &c =  0xc000006030
fmt.Println("*&c = ",*&c) // *&c =  0xc000006028
fmt.Println("**c = ",**c) // **c =  1
fmt.Println("***&*&*&*&c = ",***&*&*&*&*&c) // ***&*&*&*&c =  1
fmt.Println("x = ",x) // x =  1
理论
  • & 符号的意思是对变量取址。e.g. 变量a的地址是&a
  • * 符号的意思是对指针取值。e.g. *&a,就是变量a所在地址的值
简单的解释

*& 可以互相抵消,同时注意,*&可以抵消掉,但&*是不可以抵消的

a*&a是一样的,都是a的值,值为1 (因为*&互相抵消掉了)

a*&*&*&*&a是一样的,值为1 (因为4个*&互相抵消掉了)

展开

因为有 var b *int = &a 所以 a*&a*b是一样的,都是a的值,值为1 (把b当做&a看)

再次展开

因为有 var c **int = &b 所以

**c**&b 是一样的,把&约去后

会发现 **c*b 是一样的 (从这里也不难看出,cb也是一样的)

又因为上面得到的 &ab 是一样的 所以 **c*&a 是一样的,再次把 *& 约去后 **ca 是一样的,都是1