Go语言学习笔记,十一之指针

16 指针

变量和内存地址

1.每个变量都有内存地址,可以说通过变量来操作对应大小的内存,&符号可以获取变量的地址

  1: var a int32
  2: a = 100
  3: fmt.Printf("%d\n", a)
  4: fmt.Printf("%p\n", &a)
  1: >>> 100
  2: 0xc00004a058

2.普通变量存储的是对应类型的值,这些类型就叫值类型。指针类型存储的是一个地址,又叫引用类型

  1: var b int32 =156
  2: fmt.Printf("%d\n", b)
  3: fmt.Printf("%p\n", &b)
  4: var c *int32 = &b
  5: var d *int //没有初始化打印出来是nil
  6: fmt.Printf("%p\n", c)
  7: fmt.Printf("%v\n", d)
  1: >>> 156
  2: 0xc00004a058
  3: 0xc00004a058
  4: <nil>

指针类型变量的默认值为nil,也就是空地址

  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func main() {
  6:     a := 25
  7:     var b *int
  8:     if b == nil {
  9:             fmt.Println("b is", b)
 10:             b = &a
 11:             fmt.Println("b after initialization is", b)
 12:     }
 13: }

3.操作指针变量指向的地址里面的值

通过*符号可以获取指针变量指向的变量,还可以通过指针修改变量的值。

  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func main() {
  6:     b := 255
  7:     a := &b
  8:     fmt.Println("address of b is", a)
  9:     fmt.Println("value of b is", *a)
 10:     *b = 1000
 11:     fmt.Println(" new value of b is", *a)
 12: }
  1: >>> address of b is 0xc000010090
  2: value of b is 255 
  3: new value of b is 1000

4.指针变量传参

两个例子

  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func change(val *int) {
  6:     *val = 55
  7: }
  8: func main() {
  9:     a := 58
 10:     fmt.Println("value of a before function call is", a)
 11:     b := &a
 12:     change(b)
 13:     fmt.Println("value of a after function call is", a)
 14: }
  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func modify(arr *[3]int) {
  6:     (*arr)[0] = 90
  7: }
  8: func main() {
  9:     a := [3]int{89,90,91}
 10:     modify(&a)
 11:     fmt.Println(a)
 12: }

关于值拷贝和引用拷贝,看下面的例子

  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func swap(a int, b int) {
  6:     fmt.Printf("before a=%d b=%d\n", a, b)
  7:     a, b = b, a
  8:     fmt.Printf("after a=%d b=%d\n", a, b)
  9: }
 10: func main(){
 11:     var a int = 10
 12:     var b int = 20
 13:     swap(a, b)
 14:     fmt.Printf("in main_def a=%d b=%d\n", a, b)
 15: }

打印结果,发现main函数里面的ab的值没有改变

  1: >>> before a=10 b=20
  2: after a=20 b=10
  3: in main_def a=10 b=20

如果代码稍改下

  1: package main
  2: import (
  3:     "fmt"
  4: )
  5: func swap(a *int, b *int) {
  6:     fmt.Printf("before a=%d b=%d\n", *a, *b)
  7:     *a, *b = *b, *a
  8:     fmt.Printf("after a=%d b=%d\n", *a, *b)
  9: }
 10: func main(){
 11:     var a int = 10
 12:     var b int = 20
 13:     swap(&a, &b)
 14:     fmt.Printf("in main_def a=%d b=%d\n", a, b)
 15: }

结果就发生了改变

  1: >>> before a=10 b=20
  2: after a=20 b=10
  3: in main_def a=20 b=10

总结:*符号跟指针类型,代表指向地址的变量。而&符号跟变量,代表变量的指针。