Golang 指针简述
指针的定义
- 指针是一种存储变量内存地址(Memory Address)的变量
- 上图所示,变量 b 的值为 156,而 b 的内存地址为 0x1040a124。变量 a 存储了 b 的地址。简称 a 指向了 b; a 就是b的指针
指针的声明
- 指针的类型为: *T; 该指针指向了类型为T的变量;
- &: 用于获取变量的内存地址;
- 每次编译的过程,内存中存在的变量的地址也会不同;
- 声明的简单示例:
package main import ( "fmt" ) func main() { b := 55 // 声明指针a var a *int // 初始化赋值 // &b 获取b的内存地址 a = &b fmt.Println(b, a) }
指针的零值以及解引用
- 指针的零值:为nil
package main import ( "fmt" ) func main() { var a *int fmt.Println(a) } // 打印内容:<nil>
- 解引用:
- 获取指针指向的内存地址中的值;
- 语法: *指针变量
- 示例:
func main() { b := 55 var a *int a = &b fmt.Println(b, *a) } // 打印内容:55 55
- 利用解引用 更该变量的值:
- 示例:
func main() { b := 55 var a *int a = &b fmt.Println(b, a, *a) *a++ fmt.Println(b, a, *a) } // 打印内容: 55 0xc000058080 55 56 0xc000058080 56
- 注意 *a 是b的值, 所以*a++ 实际上是 b++, 但是a 指向的原来的b的值的内存地址,不会发生变化;
- 问? 为什么a的内存地址没有发生变化? 在*a++后, a仍然指向的是55的内存地址,而 *a 不应该是解引用出来是55 嘛? 为什么会变成56?
- 因为这里更改的实际是该内存地址的值,而不是说将该指针指向了新的值;
- 也就是说,在 *a++ 后 内存0xc000058080位置中存放的值变成了56, 所以才会这样!!!
向函数传入指针参数
- 实参中接收指针:
- 示例:
func change(a *int) { fmt.Println(a, *a) *a++ } func main() { b := 10 change(&b) fmt.Println(b) }
- 返回指针变量:
- 示例:
func change(a *int) *int { fmt.Println(a, *a) *a++ return a } func main() { b := 10 c := change(&b) fmt.Println(c, *c) }
- 尽量不要在函数中传递 指针数组;
- 切片会更方便;
- 传递指针数组示例:
package main import ( "fmt" ) func modify(arr *[3]int) { (*arr)[0] = 90 } func main() { a := [3]int{89, 90, 91} modify(&a) fmt.Println(a) } // a[x] 是 (*a)[x] 的简写形式 // 所以 (*arr)[0] 可以简写成: arr[0]: func modify(arr *[3]int) { arr[0] = 90 }
- 传递切片示例:
package main import ( "fmt" ) func modify(sls []int) { sls[0] = 90 } func main() { a := [3]int{89, 90, 91} modify(a[:]) fmt.Println(a) }