基本概念和关系

1,指针变量也是变量也有自己的内存地址,指针变量的值为另一个变量的地址

2,指针变量类型前面需要*,指针变量的值为&另一个变量(可以是指针变量)

3,&为取址运算符,可以返回给一个指针变量的值;*为取值运算符,可以获取指针值地址对应值(该值也可能是一个指针变量,所以可以多重取值**..)

4,变量类型(值的数据类型),变量(内存),值(数据)和内存地址的关系;所以指针是一种特殊的变量的类型,并且指针类型需要指定具体的值类型(地址对应值的类型)

5,*放在变量类型前和放在变量前含义不一样,&只能放在非匿名变量前使用,不能放在值前面不支持多重&&;

6,可以通过变量获取值,不能通过值找到具体的变量;变量就是一段内存,值就是该内存中的数据,变量和值的关系只是逻辑上的问题

7,一个变量的值到底是另一个指针变量还是普通值(只可能为这两种),取决于该变量类型是否为多层指针类型。只有指针才有这种特性;

8,不管是几层指针类型,指针变量的值都是地址而已,最后都要依托于普通变量的类型,只是多了一些映射关系

代码



func ptr1()  {
var a int = 5
var ptr1 *int
ptr1 = &a
fmt.Println(ptr1,*ptr1)
}

func ptr2() {
var a int = 5
var ptr1 *int
ptr1 = &a

var ptr2 **int
ptr2 = &ptr1
fmt.Println(ptr2,*ptr2,**ptr2,ptr1,*ptr1)
}

func ptr3() {
var a int = 5
var ptr1 *int
ptr1 = &a

var ptr2 **int
ptr2 = &ptr1

var ptr3 ***int
ptr3 = &ptr2
fmt.Println(ptr3,*ptr3,**ptr3,***ptr3,ptr2,*ptr2,**ptr2) //多层指针变量可以多重取值
fmt.Println(&ptr2,&ptr1,&a)//不能多层取址,因为地址已经是值
fmt.Println(&a,*ptr2) //相等
fmt.Println(&ptr1,*ptr3)//相等
}

结果:
0xc00000a0a8 5
0xc000006030 0xc00000a0e0 5 0xc00000a0e0 5
0xc000006040 0xc000006038 0xc00000a0e8 5 0xc000006038 0xc00000a0e8 5
0xc000006040 0xc000006038 0xc00000a0e8 5
0xc00000a0e8 0xc00000a0e8
0xc000006038 0xc000006038