1-Go强化(1):指针、切片、map

一、指针加强

1 - 指针地址变量空间

  • 指针:指针就是地址; 指针变量就是存储地址的变量
    • *p:解引用、间接引用
func main()  {
   
	var a int = 10
	var p *int = &a
	a = 100
	fmt.Println("a = ", a)

	*p = 250  // 借助a 变量的地址,操作a对应空间
	fmt.Println("a = ", a)
	fmt.Println("*p = ", *p)
	
	a = 1000
	fmt.Println("*p = ", *p)
}

2 - 栈帧的内存布局

  • 栈帧概念:用来给函数运行提供内存空间,取内存于stack上
    • 当函数调用时,产生栈帧
    • 函数调用结束,释放栈帧
  • 栈帧存储的对象
    • 局部变量
    • 形参(形参与局部变量存储地位等同)
    • 内存字段描述值(栈顶指针值与栈基指针值)
      在这里插入图片描述

3 - 空指针和野指针

  • Go语言中的指针:Go语言保留了指针,但与C语言指针有所不同
    • 默认值 nil
    • 操作符 “&” 取变量地址, “*” 通过指针访问目标对象
    • 不支持指针运算,不支持 “->” 运算符,直接 “.” 访问目标成员
  • 空指针:未被初始化的指针var p *int *p --> err
  • 野指针:被一片无效的地址空间初始化

4 - 函数new

  • new函数
    • 表达式new(T)将创建一个T类型的匿名变量,所做的是为T类型的新值分配并清零一块内存空间,然后将这块内存空间的地址作为结果返回,而这个结果就是指向这个新的T类型值的指针值,返回的指针类型为*T
    • new创建的内存空间位于heap上,空间的默认值为数据类型默认值。如:new(int) 则 *p为0,new(bool) 则 *p为false
    • 我们只需使用new()函数,无需担心其内存的生命周期或怎样将其删除,因为Go语言的内存管理系统会帮我们打理一切(虽然gc会帮我们回收,我们使用完后强烈建议置成nil,以提示gc进行回收)
func main()  {
   
	var p *int
	p = new (int) // 对应类型的默认值
	fmt.Println(*p) // 0
}

func main() {
   
	var p *bool
	p = new(bool) // 对应类型的默认值
	fmt.Println(*p) //false
}

5 - 左值与右值

  • 左值:等号 左边的变量,代表 变量所指向的内存空间。 (写)
  • 右值:等号 右边的变量,代表 变量内存空间存储的数据值。 (读)
var a int = 10
var b int = 20 // b是左值
a = b // b是右值

6 - 指针的函数传参

  • 函数传参方式函数传参永远是值传递(传引用传递的是地址的值)
    • 传地址(引用):将形参的地址值作为函数参数传递
    • 传值(数据据):将实参的 值 拷贝一份给形参
  • 指针的函数传参
    • 传引用:在A栈帧内部,修改B栈帧中的变量值
func swap(a, b int) {
   
	a, b = b, a
	fmt.Println("swap  a:", a, "b:", b) // swap  a: 20 b: 10
}

func swap2(x, y *int) {
   
	*x, *y = *y, *x
}

func main() {
   
	a, b := 10, 20
	swap(a, b)
	fmt.Println("swap: main  a:", a, "b:", b)  // swap: main  a: 10 b: 20
	swap2(&a, &b)                              // 传地址值
	fmt.Println("swap2: main  a:", a, "b:", b) // swap2: main  a: 20 b: 10
}

二、切片加强

1 - 切片的基础与本质

  • 为什么用切片:在Go语言当,我们几乎可以在所有的场景中,使用切片替换数组使用
    • 数组的容量固定,不能自动拓展
    • 值传递: 数组作为函数参数时,将整个数组值拷贝一份给形参
  • 切片的本质
    • 不是一个数组的指针,是一种数据结构体,用来操作数组内部元素
    • 切片并不是数组或数组指针,它通过内部指针和相关属性引用数组片段,以实现变长案
  • 数组和切片定义的区别
    • 创建数组时 ,[n]内指定数组长度
    • 创建切片时,[]内为空,或者 …(很少使用…)

2 - 切片截取、创建、append和copy

  • 切片截取切片名称 [ low : high : max ](截取数组,初始化 切片时,没有指定切片容量时, 切片容量跟随原数组(切片))
    • low:起始下标位置
    • high:结束下标位置 len = high - low
    • 容量:cap = max - low
func main() {
   
	arr := [10]int{
   1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	s := arr[1:3:5]
	fmt.Println("s = ", s)
	fmt.Println("len(s) = ", len(s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值