16 指针
变量和内存地址
1.每个变量都有内存地址,可以说通过变量来操作对应大小的内存,&符号可以获取变量的地址
1: var a int322: a = 1003: fmt.Printf("%d ", a)
4: fmt.Printf("%p ", &a)
1: >>> 1002: 0xc00004a058
2.普通变量存储的是对应类型的值,这些类型就叫值类型。指针类型存储的是一个地址,又叫引用类型
1: var b int32 =1562: fmt.Printf("%d ", b)
3: fmt.Printf("%p ", &b)
4: var c *int32 = &b5: var d *int //没有初始化打印出来是nil
6: fmt.Printf("%p ", c)
7: fmt.Printf("%v ", d)
1: >>> 1562: 0xc00004a0583: 0xc00004a0584: <nil>
指针类型变量的默认值为nil,也就是空地址
1: package main2: import (
3: "fmt"
4: )5: func main() {6: a := 257: var b *int8: if b == nil {
9: fmt.Println("b is", b)
10: b = &a11: fmt.Println("b after initialization is", b)
12: }13: }
3.操作指针变量指向的地址里面的值
通过*符号可以获取指针变量指向的变量,还可以通过指针修改变量的值。
1: package main2: import (
3: "fmt"
4: )5: func main() {6: b := 2557: a := &b8: fmt.Println("address of b is", a)
9: fmt.Println("value of b is", *a)
10: *b = 100011: fmt.Println(" new value of b is", *a)
12: }
1: >>> address of b is 0xc0000100902: value of b is 2553: new value of b is 1000
4.指针变量传参
两个例子
1: package main2: import (
3: "fmt"
4: )5: func change(val *int) {6: *val = 557: }8: func main() {9: a := 5810: fmt.Println("value of a before function call is", a)
11: b := &a12: change(b)13: fmt.Println("value of a after function call is", a)
14: }
1: package main2: import (
3: "fmt"
4: )5: func modify(arr *[3]int) {6: (*arr)[0] = 907: }8: func main() {9: a := [3]int{89,90,91}10: modify(&a)11: fmt.Println(a)12: }
关于值拷贝和引用拷贝,看下面的例子
1: package main2: import (
3: "fmt"
4: )5: func swap(a int, b int) {6: fmt.Printf("before a=%d b=%d ", a, b)
7: a, b = b, a8: fmt.Printf("after a=%d b=%d ", a, b)
9: }10: func main(){11: var a int = 1012: var b int = 2013: swap(a, b)14: fmt.Printf("in main_def a=%d b=%d ", a, b)
15: }
打印结果,发现main函数里面的ab的值没有改变
1: >>> before a=10 b=202: after a=20 b=103: in main_def a=10 b=20
如果代码稍改下
1: package main2: import (
3: "fmt"
4: )5: func swap(a *int, b *int) {6: fmt.Printf("before a=%d b=%d ", *a, *b)
7: *a, *b = *b, *a8: fmt.Printf("after a=%d b=%d ", *a, *b)
9: }10: func main(){11: var a int = 1012: var b int = 2013: swap(&a, &b)14: fmt.Printf("in main_def a=%d b=%d ", a, b)
15: }
结果就发生了改变
1: >>> before a=10 b=202: after a=20 b=103: in main_def a=20 b=10
总结:*符号跟指针类型,代表指向地址的变量。而&符号跟变量,代表变量的指针。