指针

一、什么是指针

  • 指针也是一种变量,但是它的功能只是用来存储变量内存地址(Memory Address),即指针变量的值为其他变量的内存地址

  • 指针是变量,所以它本身也有内存地址

  • 内存地址都是属于 int 类型的值

  • Go中的指针是不支持运算的(有些语言可以,如C语言)

    • package main
      
      func main() {  
          b := [...]int{109, 110, 111}
          p := &b
          p++  // 不能进行运算,会报错 main.go:6: invalid operation: p++ (non-numeric type *[3]int)
      }
      

二、指针的定义

  • 最关键的两个符合

    • & 表示取变量的内存地址,* 表示通过地址找到值
  • 指针变量的类型为 *T,T为数据类型

  • 指针的空值为nil

1. 指针的声明
var d *string  // 声明了一个指针类型的字符串,恒等于 nil
var f *[3]int  // 声明了一个指针类型的数组,恒等于 nil
var g *[]int  // 声明了一个指针类型的切片,恒等于 nil

package main  
import (  
    "fmt"
)

2. 指针实例

func main() {  
    b := 255
    a := &b  // & 表示取变量的内存地址
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)  //  * 表示取指针的指向的值
}

/*
打印结果:

address of b is 0x1040a124  
value of b is 255
*/

三、向函数传递指针参数

  • 分为三种类型的指针参数
    • 数字、字符串类型的指针
    • 数组类型的指针(不推荐,推荐替换为直接传切片)
    • 切片类型(切片类型无需传递其指针,用来替代数组类型指针)

1. 传入字符串类型的指针

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)
}


/*
value of a before function call is 58  
value of a after function call is 55

可以看到,在函数中修改了传入的参数,但是,在函数外,a的值也同步被修改了
若不用指针,直接将a传入函数,则最后打印的a 仍是 58
*/

2. 传入数组类型的指针

  • 假如我们想在函数内部修改一个数组,并希望函数外部的数组也同步修改,有两种方式
    • 一种解决方案是把一个指向数组的指针传递给这个函数
    • 另一种是传递该数组的切片(因为切片的结构就包括底层数组的指针,其本身没有值)
  • 且传递数组类型的指针时,在函数内部,无需用符号 * 进行取值,可直接将参数当数组使用,Go的语法糖
package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  // 接收 数组类型的指针 参数
    arr[0] = 90  // 本来应该写成  (*arr)[0] = 90 ,但是 go对数组指针做个处理
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(&a)
    fmt.Println(a)  // [90 90 91] ,可以看到数组a的第一个元素也被修改为90了
}

3. 传入切片

  • 传入切片类型,能使得代码更加简洁,且更符合Go语言的习惯
package main

import (  
    "fmt"
)

func modify(sls []int) {  // 接收 切片类型 参数
    sls[0] = 90
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(a[:])
    fmt.Println(a)  // [90 90 91] ,传切片时,数组a的第一个元素也被修改为90了
}
posted @ 2024-02-26 16:53  BigSun丶  阅读(28)  评论(0)    收藏  举报