1. 程式人生 > >Go語言學習筆記(十一)之指標

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

總結:*符號跟指標型別,代表指向地址的變數。而&符號跟變數,代表變數的指標。