golang的指针
Posted 404space
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang的指针相关的知识,希望对你有一定的参考价值。
在说golang的指针之前,先啰嗦一下关于计算机的东西。众所周知,1TB=1024GB,1GB=1024MB,1MB=1024KB,1KB=1024字节。
go中int类型的大小(引自《Go语言编程》)
在go语言中,内存是自动分配的,也就是说,我声明一个变量,go的编译器会根据你声明的变量类型来自动分配适当的内存(这里不涉及内存分配的东西,会在后续的文章中来介绍)
此时,声明并初始化一个int类型的变量a = 2
package main import "fmt" func main() { var a int = 2 c := a fmt.Printf("a的内存地址:%x ",&a) fmt.Printf("c的内存地址:%x ",&c) }
运行后发现a和c指向同一块内存地址。
此时,修改c,令其等于另一个值
package main import "fmt" func main() { var a int = 2 c := a fmt.Printf("a的内存地址:%x ",&a) fmt.Printf("c的内存地址:%x ",&c) //修改c的值 c = 12 fmt.Printf("修改之后c的内存地址:%x ",&c) }
运行之后发现,,说明此时c指向了另一个内存地址。
这一点明白之后,我们来看golang的指针。
package main import "fmt" func main() { var a int = 2 var pa *int = &a fmt.Printf("a的内存地址是:%x ",&a) fmt.Printf("pa的内存地址是:%x ",pa) }
在go语言中,&为取地址符,用来获取某个类型变量的地址,我们可以叫pa *int为一个int类型的指针,所以这句话可以理解为:让一个名为pa的int类型的指针,指向a的内存地址。运行之后发现:
a和pa的内存地址相同。(pa保存的值是一个地址)我们可以使用*pa来修改这个变量指向的地址的值。
import "fmt"
func main() {
var a int = 2
var pa *int = &a //一个名叫pa的int型指针指向a的地址
fmt.Printf("修改前a的内存地址是:%x ",&a)
fmt.Printf("修改前pa的内存地址是:%x ",pa)
//修改值
*pa = 5
fmt.Printf("修改后a的内存地址是:%x ",&a)
fmt.Printf("修改后pa的内存地址是:%x ",pa)
fmt.Println("a的值是:",a)
fmt.Println("*pa的值是:",*pa)
}
运行后发现 修改之后,原变量a的值和*pa的值相同,a的内存地址是原始的内存地址且和pa保存的内存地址也相同,所以此次修改了原来a内存地址中保存的数值。
接下来我们看一下参数传递。在c和c++可以值传递,也可以引用传递;java和python绝大多数为引用传递。那么在go中是使用的什么方式呢?其实,Go只有值传递一种方式,但是我们可以使用指针的方式来协助。
package main import "fmt" func incresment(a int) { a += 1 fmt.Println("自增后的值为:",a) } func main() { a := 5 incresment(a) fmt.Println("a的值为:",a) }
运行后可以发现go使用的是值传递的方式,也就是说,将参数做了一次拷贝。
看到这儿可能有的人会问:函数中参数比较少还好,如果有很多参数,岂不是要浪费很多时间?回过头来看看,前边说过了,可以使用指针来作辅助。
我们再来看一个例子:
package main import "fmt" func swap(a, b int) { var temp int temp = a a = b b = temp fmt.Println("交换后a的值是:",a) fmt.Println("交换后b的值是:",b) } func main() { a := 5 b := 6 swap(a,b) fmt.Println("a的值是:",a) fmt.Println("b的值是:",b) }
因为go是值传递的方式,所以运行后只在swap()函数的作用域内正确,此时我们借助指针来实现这个交换位置的函数
package main import "fmt" func swap(a, b *int) { var temp int temp = *a *a = *b *b = temp } func main() { a := 5 b := 6 fmt.Println("交换前a的值是:",a) fmt.Println("交换前b的值是:",b) fmt.Println("------------------") swap(&a,&b) fmt.Println("交换后a的值是:",a) fmt.Println("交换后b的值是:",b) }
swap函数中的参数是两个int类型的指针,前边提到了,这个指针应该指向一个内存地址,所以在main函数中调用swap时需要传入a和b的地址,此时的执行结果是也就是说,如果我们需要对原数据进行修改的话,需要使用指针,这在数据结构和算法中会经常用到。
以上是关于golang的指针的主要内容,如果未能解决你的问题,请参考以下文章