Go指针数组和数组指针的具体使用

 更新时间:2024年03月21日 09:41:49   作者:小欧不菜  
go语言跟c语言一样,指针数组和数组指针概念容易搞混,本文主要介绍了Go指针数组和数组指针的具体使用,具有一定的参考价值,感兴趣的可以了解一下

这个章节将会简单讲Go 的指针数组和数组指针。

我相信学习Go的同学们,应该都是接触过别的语言吧,Go应该是大部分同学的第二门甚至第好几门的语言吧,所以大家应该都有一定的语言基础了,言归正传。

先说概念:

指针数组就是一个数组,这个数组的元素是指针(C语言也是这样)

数组指针就是一个指针,这个指针指向一个数组(C语言也是这样)

好了,概念讲完了非常简单,直接上代码

一、指针数组

func My_Print(p [3]*int) {
	fmt.Println(p)
	for _, val := range p {
		fmt.Printf("%d ", *val)
	}
	fmt.Println()
}

func F_1() {
	a1, a2, a3 := 77, 88, 99
	p1 := [3]*int{&a1, &a2, &a3}
	p2 := F_2(p1)
	fmt.Printf("After modification")
	My_Print(p2)
}

func F_2(p [3]*int) [3]*int {
	fmt.Printf("Before modification")
	My_Print(p)

	for i := 0; i < 3; i++ { //我们改变这个指针数组里面的指针的内容
		*(p[i]) = i
	}
	return p
}

func main() {
	F_1()
}

我们直接讲代码,这里有三个函数My_Print(p [3]*int)、F_1()、F_2(p [3]*int) [3]*int:

My_Print(p [3]*int)   形参是一个指针数组 ,这就是一个打印这个指针数组里面的内容,数组里面的内容是指针(指向一个地址),地址里面是一个整形变量,这个函数就是把它们都打印出来。

F_1()    这个函数就是顶一个指针数组并且初始化,指针数组里面放指针所以我们给他初始化三个地址,并且把这个指针数组当做参数传给F_2()

F_2()   这个函数会先调用My_Print打印形参内容,在修改这个形参。

运行结果如下:

Before modification[0xc000134000 0xc000134008 0xc000134010]
77 88 99 
After modification[0xc000134000 0xc000134008 0xc000134010]
0 1 2 

可以看出修改前和修改后 ,指针数组里面的指针(这个地址)并没有变,但是这个指针里的内容已经被改变了。

二、数组指针

直接上代码:

func main() {
	//F_1()
	F_3()
}

func F_3() {
	var p *[3]int
	arr := [3]int{1, 2, 3}
	p = &arr
	fmt.Printf("p = %p,arr = %p\n", p, &arr)

	F_4(p)
	fmt.Println("F_3():", p)
}

func F_4(p *[3]int) {
	// 这里也算是Go的一个语言特性吧,编译器可以认为p是arr的地址,也可以认为p是arr的引用
	fmt.Println("F_4():", p)
	p[0] = 11
	p[1] = 22
	p[2] = 33
	fmt.Println("F_4():", p)
	(*p)[0] = 99
	(*p)[1] = 88
	(*p)[2] = 77
	fmt.Println("F_4():", p)
}

运行结果如下:

p = 0xc000122000,arr = 0xc000122000
F_4(): &[1 2 3]
F_4(): &[11 22 33]
F_4(): &[99 88 77]
F_3(): &[99 88 77]

这个数组指针,倒是没啥难懂的,但是这个可能会让大家疑惑的应该就是那个F_4()函数里面那样写的问题了。这应该是和Go的GC机制有关。我们在go学习中提过,一个问题就是一个指针指向一个局部变量然后返回这个指针,可是在外部这个指针依旧可以访问到这个变量的内容。 

在Go中一个变量如果在他作用域之外还有存在它的引用时,他是不会被内存回收走的,它会存在一个引用它的计数值,但又多一个它的引用,那它的计数值加一,反之减一。直到它的引用为零时,GC就会回收这份空间。

个人理解:所以这个形参p也是跟这个GC机制有关,写法上它就是arr的地址,但是编译器也可以认为他是arr的引用。

最后分享

不管是学Go或者学C的同学,可能都有点分不清数组指针和指针数组,这里是我自己分辨他们两的方法:

概念上,正如上面所说的:

指针数组就是一个数组,这个数组的元素是指针(C语言也是这样)

数组指针就是一个指针,这个指针指向一个数组(C语言也是这样)

写法上:

[] 在 * 前面,那他就是一个数组,所以是指针数组,反之数组指针。(在Go中我是这里记的)

(*a)[], * 被括号起来,说明要a先跟 * 结合,所以这个一个指针,也就是数组指针,反之指针数组(C语言中我是这么记的)

到此这篇关于Go指针数组和数组指针的具体使用的文章就介绍到这了,更多相关Go指针数组和数组指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang的strings.Split()踩坑记录

    Golang的strings.Split()踩坑记录

    工作中,当我们需要对字符串按照某个字符串切分成字符串数组数时,常用到strings.Split(),本文主要介绍了Golang的strings.Split()踩坑记录,感兴趣的可以了解一下
    2022-05-05
  • golang的HTTP基本认证机制实例详解

    golang的HTTP基本认证机制实例详解

    这篇文章主要介绍了golang的HTTP基本认证机制,结合实例形式较为详细的分析了HTTP请求响应的过程及认证机制实现技巧,需要的朋友可以参考下
    2016-07-07
  • GoLang Time时间操作函数讲解

    GoLang Time时间操作函数讲解

    在日常开发中,我们避免不了时间的使用,我们可能需要获取当前时间,然后格式化保存,也可能需要在时间类型与字符串类型之间相互转换等。本文将会对 Go time 包里面的常用函数和方法进行介绍,需要的可以参考一下
    2023-01-01
  • go doudou应用中使用枚举类型教程示例

    go doudou应用中使用枚举类型教程示例

    这篇文章主要为大家介绍了go doudou应用中使用枚举类型教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Go语言框架快速集成限流中间件详解

    Go语言框架快速集成限流中间件详解

    这篇文章主要为大家介绍了Go语言框架快速集成限流中间件详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Go语言func匿名函数闭包示例详解

    Go语言func匿名函数闭包示例详解

    这篇文章主要为大家介绍了Go语言func匿名函数闭包示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言使用Cobra实现强大命令行应用

    Go语言使用Cobra实现强大命令行应用

    Cobra是一个强大的开源工具,能够帮助我们快速构建出优雅且功能丰富的命令行应用,本文为大家介绍了如何使用Cobra打造强大命令行应用,感兴趣的小伙伴可以了解一下
    2023-07-07
  • 一文带你掌握Go语言并发模式中的Context的上下文管理

    一文带你掌握Go语言并发模式中的Context的上下文管理

    在 Go 的日常开发中,Context 上下文对象无处不在,无论是处理网络请求、数据库操作还是调用 RPC 等场景,那你真的熟悉它的正确用法吗,随着本文一探究竟吧
    2023-05-05
  • 详解玩转直播系列之消息模块演进

    详解玩转直播系列之消息模块演进

    本篇文章针对秀场直播,简单地描述一下消息模型,说明一下我们消息模型的架构,并结合我们一年以来,通过处理不同的业务线上问题,来进行演进式的消息模型架构的升级与调整,将此整理成文,并分享給大家
    2021-06-06
  • GoLang函数栈的使用详细讲解

    GoLang函数栈的使用详细讲解

    这篇文章主要介绍了GoLang函数栈的使用,我们的代码会被编译成机器指令并写入到可执行文件,当程序执行时,可执行文件被加载到内存,这些机器指令会被存储到虚拟地址空间中的代码段,在代码段内部,指令是低地址向高地址堆积的
    2023-02-02

最新评论