这个章节将会简单讲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指针数组和数组指针内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论