4.9 指针
...大约 2 分钟
4.9 指针
程序在内存存储其值,每个内存块(或字)有一个地址,通常使用十六进制数表示
Golang的取址符为&
,在变量前使用就会返回响应变量的内存地址,
内存地址可以存储在名为指针的特殊数据类型中,指针变量的缩写通常为ptr。
下面的例子中intP是一个int型指针:*int
,intP存储了i1的内存地址;它指向了i1的位置,引用了变量i1
var intP *int
var i1 = 5
//intP指向i1
intP = &i1
一个指针变量可以指向任何一个值的内存地址,指向的值的内存地址,在32位机器中占用4个字节,在64位机器中占用8个字节,并且与它所指向的值的大小无关。
当一个指针未被分配到任何变量时,其值为nil。
不能获取字面量或常量的地址,例如:
const i = 5
ptr := &i //error: cannot take the address of i
ptr2 := &10 //error: cannot take the address of 10
Go 中的指针运算是不合法的,如 c = *p++
。
间接引用
可以在指针类型前使用符号*
来获取指针所指向的内容,这里的 *
号是一个类型更改器,使用指针来引用一个值被称为反引用(或者内容或者间接引用)。
s := "good bye"
var ptrS *string = &s
*ptrS = "ciao"
fmt.Printf("Here is the pointer ptrS :%p \n", ptrS)
fmt.Printf("Here is the string *ptrS : %s\n", *ptrS)
fmt.Printf("Here is the string s : %s\n", s)
Here is the pointer ptrS :0xc00009e220
Here is the string *ptrS : ciao
Here is the string s : ciao
上述例子中,ptrS
是指向变量s的指针,在对*ptrS
赋值后,s的值也发生了改变
内存示意图如下:
不能获取字面量或常量的地址,例如:
const i = 5
ptr := &i //error: cannot take the address of i
ptr2 := &10 //error: cannot take the address of 10
对一个空指针的反向引用是不合法的,并且会使程序崩溃:
package main
func main() {
var p *int = nil
*p = 0
}
// in Windows: stops only with: <exit code="-1073741819" msg="process crashed"/>
// runtime error: invalid memory address or nil pointer dereference
应用
可以传递一个变量的引用(如函数的参数),这样不会传递变量的拷贝。指针传递是很廉价的,只占用 4 个或 8 个字节。当程序在工作中需要占用大量的内存,或很多变量,或者两者都有,使用指针会减少内存占用和提高效率。被指向的变量也保存在内存中,直到没有任何指针指向它们,所以从它们被创建开始就具有相互独立的生命周期。
Powered by Waline v2.15.2