Golang 指针

一、指针简介

当我们运行一段程序,首先程序会被从硬盘读取到内存中,每块内存都会有一个地址,用来标识数据在内存中存储的位置,而为了保存一个数据在内存中的地址,我们就需要指针变量。

区别于 C/C++ 中的指针,Go 语言中的指针不能进行偏移和运算,是安全指针,因此Go语言中的指针操作非常简单,我们只需要记住两个符号:&(取地址)和 *(根据地址取值)。

二、指针的使用

1. 指针地址

Go 语言中使用 & 字符放在变量前面对变量进行取地址操作:

package main

import "fmt"

func main() {
	a := "cdc"
	b := &a

	fmt.Printf("变量b的类型:%T\n", b)  // 变量b的类型:*string

	// 使用 %p 接收指针类型的值
	fmt.Printf("变量b的值:%p\n", b)  // 变量b的值:0xc000040240

	// 变量b的值为变量a的内存地址,可以继续对变量b进行取地址操作
	c := &b
	fmt.Printf("b的内存地址为:%p\n", c)  // b的内存地址为:0xc000006028
	d := &c
	fmt.Printf("c的内存地址为:%p\n", d)  // c的内存地址为:0xc000006038
}

在内存中,上述几个变量的存储如下:
在这里插入图片描述

2. 指针类型

用于接收指针地址的变量对应的数据类型为指针类型,Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int*int64*string 等。指针类型也可以直接声明使用。

package main

import "fmt"

func main() {
	// 声明一个整型类型的指针
	var ptr1 *int

	// 声明一个数组类型的指针
	var ptr2 *[3]int

	// 声明一个值为整型类型的数组
	var ptr3 [3]*int

	num := 10
	ptr1 = &num
	fmt.Println(ptr1)  // 0xc00000a0b8

	array1 := [3]int{10, 20, 30}
	ptr2 = &array1
	fmt.Println(ptr2)  // &[10 20 30]

	array2 := [3]*int{}
	for i := 0; i < 3; i++ {
		array2[i] = &i
	}
	ptr3 = array2
	fmt.Println(ptr3)  // [0xc00000a0f8 0xc00000a0f8 0xc00000a0f8]
}

3. 通过指针操作值

3.1 取值

在对普通变量使用 & 操作符取地址后会获得这个变量的指针,然后可以对指针使用 * 操作获取地址对应内存中存储的值。

package main

import "fmt"

func main() {
	a := 10
	b := &a
	c := &b
	d := &c

	fmt.Printf("d:%v  %v\n", d, *d)  // d:0xc000006030  0xc000006028
	fmt.Printf("c:%v  %v\n", c, *c)  // c:0xc000006028  0xc00000a0b8
	fmt.Printf("b:%v  %v\n", b, *b)  // b:0xc00000a0b8  10

	// 只要时指针,就可以取值
	fmt.Println(***d)  // 10
    
    // 也可以通过取值操作对原来的值进行修改
    *b = 100
    fmt.Println(a)  // 100
}
3.2 修改值

函数传值时,尤其是针对值类型的变量,都是先将变量的值拷贝一份,然后传递给函数使用,即在函数中修改变量的值不会影响原来的变量:

package main

import "fmt"

func changeValue1(num int) int {
	num = 100
	return num

}

func main() {
	num := 10
	changeValue1(num)
	fmt.Println(num)  // 10

}

如果想要原来的值也随着函数的操作而修改,可以通过指针传值的方式:

package main

import "fmt"

func changeValue2(num *int) {
	*num = 100

}

func main() {
	num := 10

	changeValue2(&num)
	fmt.Println(num)  // 100
}

使用指针传参的好处,除了可以实现修改原来参数的值的功能,还可以减少传参时的内存消耗,例如:如果一个参数是一个字符串类型的值,且内容比较大,那所有要使用该变量的函数,都要将其拷贝一份,再拿过来使用,因此会占用很大的内存。但是如果只传递该变量的内存地址,则能减小内存不必要的浪费。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值