1:什么是指针
指针是一种存储变量内存地址(Memory Address)的变量
a:0x101101124
b:156 ;addrese - 0x101101124
变量 b 的值为 156,而 b 的内存地址为 0x1040a124。变量 a 存储了 b 的地址。我们就称 a 指向了 b
2:指针的声明
指针变量的类型为 *T,该指针指向一个 T 类型的变量。
package main
import (
"fmt"
)
func main() {
b := 255
var a *int = &b //& 操作符用于获取变量的地址
fmt.Printf("Type of a is %T\n", a)
fmt.Println("address of b is", a)
}
我们把 b 的地址赋值给 *int 类型的 a。我们称 a 指向了 b。当我们打印 a 的值时,会打印出 b 的地址。程序将输出:
Type of a is *int
address of b is 0x101101124 //由于 b 可能处于内存的任何位置,你应该会得到一个不同的地址
3: 指针的零值
指针的零值是nil
package main
import (
"fmt"
)
func main() {
a := 25
var b *int
if b == nil {
fmt.Println("b is", b)
b = &a
fmt.Println("b after initialization is", b)
}
}
上面的程序中,b 初始化为 nil,接着将 a 的地址赋值给 b。程序会输出:
b is <nil>
b after initialisation is 0x101101124
4:指针的解引用
指针的解引用可以获取指针所指向的变量的值。将 a 解引用的语法是 *a
package main
import (
"fmt"
)
func main() {
b := 255
a := &b
fmt.Println("address of b is", a)
fmt.Println("value of b is", *a)
}
在上面程序,我们将 a 解引用,并打印了它的值。不出所料,我们会打印出 b 的值。程序会输出:
address of b is 0x101101124
value of b is 255
我们再编写一个程序,用指针来修改 b 的值
package main
import (
"fmt"
)
func main() {
b := 255
a := &b
fmt.Println("address of b is", a)
fmt.Println("value of b is", *a)
*a++
fmt.Println("new value of b is", b)
}
我们把 a 指向的值加 1,由于 a 指向了 b,因此 b 的值也发生了同样的改变。于是 b 的值变为 256。程序会输出:
address of b is 0x101101124
value of b is 255
new value of b is 256
5:向函数传递指针参数
package main
import (
"fmt"
)
func change(val *int) {
*val = 55
}
func main() {
a := 58
fmt.Println("value of a before function call is",a)
b := &a
change(b)
fmt.Println("value of a after function call is", a)
}
在上面程序中的,我们向函数 change 传递了指针变量 b,而 b 存储了 a 的地址。在 change 函数内使用解引用,修改了 a 的值。该程序会输出:
value of a before function call is 58
value of a after function call is 55
6:不要向函数传递数组的指针,而应该使用切片
直接代码示例说明
package main
import (
"fmt"
)
func modify(arr *[3]int) {
(*arr)[0] = 90
arr[1] = 91//a[x] 是 (*a)[x] 的简写形式
}
func modify2(sls []int) {
sls[0] = 90
}
func main() {
a := [3]int{89, 90, 91}
modify(&a) //传递数组指针方式
fmt.Println(a)
modify2(a[:])//使用切片 更加简洁
}