go初学篇(五)之指针

前言

对于指针,C语言可是靠着这个东西混的游刃有余,go创作初继承了大量C的属性,所以指针就是必不可少的,而go的指针和C也有很大不同。咱们也不用深究不同点,只要知道指针是存储一个变量内存地址的,它本身也是一个变量。

1. 获取变量的地址

  在go语言中取地址符为&,往往放到一个变量的前面,用来返回相应的内存地址
   var a int = 1

   fmt.Printf("变量的地址: %x\n", &a)
   变量的地址: c0000aa058

2. 声明指针

  一般的格式为*T,T表示的是变量类型
    var a int = 10 /* 声明一个实际变量 */
	var b *int     /* 声明一个指针变量 */

	b = &a /* 指针变量的存储地址 */

	fmt.Printf("a 变量的地址是: %x\n", &a)

	/* 指针变量的存储地址 */
	fmt.Printf("ip 变量的存储地址: %x\n", b)

	/* 使用指针访问值 */
	fmt.Printf("*ip 变量的值: %d\n", *b)
a 变量的地址是: c000018098
ip 变量的存储地址: c000018098
*ip 变量的值: 10             

如果一个指针被定义了但是没有赋予任何变量,那么它就是一个空指针,值为nil

3.指针的一系列操作

获取指针就是访问指针指向变量的值,语法就是*a

3.1操作指针改变变量的数值

    a := 100
	b := &a
	fmt.Println("a的地址是", b)
	fmt.Println("a的值是", *b)
	*b++
	fmt.Println("a的新值是", a)
a的地址是 0xc000018098
a的值是 100  
a的新值是 101

3.2用指针在函数里传参


func foo(a *int) {
	*a = 12
}
func main() {
	b := 15
	fmt.Println("在改变之前b的值为", b)
	c := &b
	foo(c)
	fmt.Println("在改变之后b的值为", b)
}
在改变之前b的值为 15
在改变之后b的值为 12

如果函数的参数是数组,就不要用指针指向它,也就是说,函数的参数不能是用指针指向的数组,要使用切片

func foo(arr *[3]int) {
	arr[0] = 90
}
func main() {
	a := [3]int{89, 90, 91}
	foo(&a)
	fmt.Println(a)
}

[90 90 91]

虽然上面的结果正确,但这并不是实现这一目标好用的方法,相对而言还显得复杂,我们不妨用切片来试试

func foo(arr []int) {
	arr[0] = 90
}
func main() {
	a := [3]int{89, 90, 91}
	foo(a[:])
	fmt.Println(a)
}
[90 90 91]

在开发的过程中我们有可能需要保存原数组,指针就是不错的选择

const MAX int = 3

func main() {
	a := []int{110, 111, 112}
	var i int
	var arr [MAX]*int

	for i = 0; i < MAX; i++ {
		arr[i] = &a[i] /* 整数地址赋值给指针数组 */
	}

	for i = 0; i < MAX; i++ {
		fmt.Printf("a[%d] = %d\n", i, *arr[i])
	}
}
a[0] = 110
a[1] = 111
a[2] = 112

4.指向指针的指针
如果一个指针存的是另一个指针的地址,则这个指针变量就是指向指针变量的指针

    var a int
	var arr *int
	var aarr **int

	a = 100

	/* 指针 arr 地址 */
	arr = &a

	/* 指向指针 arr 地址 */
	aarr = &arr

	/* 获取 aarr 的值 */
	fmt.Printf("变量 a = %d\n", a)
	fmt.Printf("指针变量 *arr = %d\n", *arr)
	fmt.Printf("指向指针的指针变量 **aarr = %d\n", **aarr)
变量 a = 100
指针变量 *arr = 100
指向指针的指针变量 **aarr = 100

函数的参数是指针

func swap(x *int, y *int) {
	var tem int
	tem = *x /* 保存 x 地址的值 */
	*x = *y  /* 将 y 赋值给 x */
	*y = tem /* 将 temp 赋值给 y */
}
func main() {
	/* 定义局部变量 */
	var a int = 10
	var b int = 20

	fmt.Printf("变化前 a 的值为 : %d\n", a)
	fmt.Printf("变化前 b 的值为 : %d\n", b)

	/* 调用函数用于交换值
	 * &a 指向 a 变量的地址
	 * &b 指向 b 变量的地址
	 */
	swap(&a, &b)

	fmt.Printf("变化后 a 的值为 : %d\n", a)
	fmt.Printf("变化后 b 的值为 : %d\n", b)
}

变化前 a 的值为 : 10
变化前 b 的值为 : 20
变化后 a 的值为 : 20
变化后 b 的值为 : 10
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值