4.9 指针

Kesa...大约 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的值也发生了改变

内存示意图如下:

image-20230503103828518
image-20230503103828518

不能获取字面量或常量的地址,例如:

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