目录
指针概念
使用指针流程
1、空指针
2、指针数组
3、指向指针的指针
多重指针
4、指针作为函数参数
Go 语言的取地址符是 &
,放到一个变量前使用就会返回相应变量的内存地址。
指针概念
一个指针变量指向一个值的内存地址
类似于变量和常量,在使用指针前需要声明指针。
var var_name =*var_type
使用指针流程
- 定义指针变量
- 为指针变量赋值
- 访问指针变量中指向地址的值
在指针类型前面加上*号(前缀)来获取指针所指向的内容
package main
import "fmt"
//指针声明和赋值
func main() {
var (
a int = 20 //实际变量
ip *int //指针变量
)
//把a的地址赋值给指针ip
ip = &a
fmt.Println("a的值为:", a)
fmt.Println("a的地址为:", &a)
fmt.Println("指针ip的值为:", ip)
fmt.Println("指针ip指向的值为:", *ip)
}
##
a的值为: 20
a的地址为: 0xc0000aa058
指针ip的值为: 0xc0000aa058
指针ip指向的值为: 20
1、空指针
当一个指针被定义后没有分配到任何变量时,它的值为nil
nil 指针也称为空指针
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr
。
package main
import "fmt"
//指针声明和赋值
func main() {
var ptr *int
fmt.Println(ptr)
}
##
<nil>
2、指针数组
package main
import "fmt"
func main() {
var ptr [3]*int
var a = [3]int{10, 20, 30}
for i := 0; i < len(a); i++ {
ptr[i] = &a[i]
}
for j := 0; j < len(ptr); j++ {
fmt.Println(*ptr[j])
}
}
##
10
20
30
3、指向指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:
package main
import "fmt"
/*指向指针的指针*/
func main() {
var (
a int //变量
ptr *int //指针
pptr **int //指针的指针
)
//变量赋值
a = 1000
//ptr赋值a的地址
ptr = &a
//pptr赋值ptr的地址
pptr = &ptr
fmt.Println("a的值", a)
fmt.Println("a的地址", ptr)
fmt.Println("指针ptr指向的值", *ptr)
fmt.Println("指针pptr指向的值", *pptr)
fmt.Println("指针pptr指向指针ptr指向的值", **pptr)
fmt.Println("指针pptr的地址", &pptr)
}
##
a的值 1000
a的地址 0xc0000aa058
指针ptr指向的值 1000
指针pptr指向的值 0xc0000aa058
指针pptr指向指针ptr指向的值 1000
指针pptr的地址 0xc0000ce020
多重指针
package main
import "fmt"
func main() {
var a int = 5
//把ptr指针 指向ss所在地址
var ptr *int = &a
//开辟一个新的指针,指向ptr指针指向的地方
var pts *int = ptr
//二级指针,指向一个地址,这个地址存储的是一级指针的地址
var pto **int = &ptr
//三级指针,指向一个地址,这个地址存储的是二级指针的地址,二级指针同上 pt3--->pto--->ptr--->5 pts--->5
var pt3 ***int = &pto
fmt.Println(
"a的地址:", &a, "值", a, "\n",
"ptr指针所在地址:", &ptr, "\n ",
"ptr指向的地址:", ptr, "\n",
"ptr指针指向地址对应的值", *ptr, "\n",
"pts指针所在地址:", &pts,
"\n pts指向的地址:", pts,
"\n pts指针指向地址对应的值:", *pts, "\n\n",
"pto指针所在地址:", &pto,
"\n pto指向的指针(ptr)的存储地址:", pto,
"\n pto指向的指针(ptr)所指向的地址: ", *pto,
"\n pto最终指向的地址对应的值(a)", **pto, "\n\n",
"pt3指针所在的地址:", &pt3,
"\n pt3指向的指针(pto)的地址:", pt3, //等于&*pt3,
"\n pt3指向的指针(pto)所指向的指针的(ptr)地址", *pt3, //等于&**pt3,
"\n pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a):", **pt3, //等于&***pt3,
"\n pt3最终指向的地址对应的值(a)", ***pt3)
}
##
a的地址: 0xc000014098 值 5
ptr指针所在地址: 0xc000006028
ptr指向的地址: 0xc000014098
ptr指针指向地址对应的值 5
pts指针所在地址: 0xc000006030
pts指向的地址: 0xc000014098
pts指针指向地址对应的值: 5
pto指针所在地址: 0xc000006038
pto指向的指针(ptr)的存储地址: 0xc000006028
pto指向的指针(ptr)所指向的地址: 0xc000014098
pto最终指向的地址对应的值(a) 5
pt3指针所在的地址: 0xc000006040
pt3指向的指针(pto)的地址: 0xc000006038
pt3指向的指针(pto)所指向的指针的(ptr)地址 0xc000006028
pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a): 0xc000014098
pt3最终指向的地址对应的值(a) 5
4、指针作为函数参数
函数默认是指针类型,要交换数字得用引用类型,用指针
package main
import "fmt"
/*实际值传递*/
func main() {
var (
a int = 10
b int = 20
)
fmt.Println("交换前a=", a)
fmt.Println("交换前b=", b)
// swap(a, b)
swap(&a, &b)
fmt.Println("交换后a=", a)
fmt.Println("交换后b=", b)
}
func swap(x *int, y *int) {
*x, *y = *y, *x
}
##
交换前a= 10
交换前b= 20
交换后a= 20
交换后b= 10