指针
一个变量对应一个保存了变量对应类型值的内存空间。普通变量在声明语句创建时被绑定到一个变量名,比如叫x的变量,但是还有很多变量始终以表达式方式引入,例如x[i]或x.f变量。所有这些表达式一般都是读取一个变量的值,除非它们是出现在赋值语句的左边,这种时候是给对应变量赋予一个新的值。
一个指针的值是另一个变量的地址。一个指针对应变量在内存中的存储位置。并不是每一个值都会有一个内存地址,但是对于每一个变量必然有对应的内存地址。通过指针,我们可以直接读或更新对应变量的值,而不需要知道该变量的名字(如果变量有名字的话)。
声明指针
指针是一种地址值,这个地址值代表着计算机内存空间中的某个位置。指针变量就是存放地址值的变量,指针变量的声明格式如下:
var 指针变量名 *数据类型
例:var p *int
一般情况下,我们将指针变量的类型声明为*int,变量名为“p”开头(指代“point”)的单词,如“p”或“ptr”。
package main
import "fmt"
func main(){
var p *int
fmt.Println(p)
}
执行结果:
<nil>
由于指针变量未指向任何地址,所以打印值为nil。
取指针变量地址
取址运算符"&"用于获取对象地址。
package main
import "fmt"
func main(){
num := 1
var p *int = &num //将取得num的地址值赋给指针变量
fmt.Println("num变量的地址为:",p)
fmt.Println("指针变量p的地址为:",&p)
}
执行结果:
num变量的地址为: 0xc042066080
指针变量p的地址为: 0xc042086018
由于指针变量本身也是变量,因此指针变量在计算机内存中也有自己的地址。需注意的是,读者运行上述程序时得到的实际结果可能与以上结果不符,甚至多次运行该程序得到的结果可能都不一致,这是由于变量在内存中的位置都是随机分配的。
获取指针所指向的内容
指针变量存储的值为地址值,通过在指针变量前面加上“*”符号可以获取指针所指向地址值的内容。
package main
import "fmt"
func main(){
num := 1
var p *int = &num //将取得num的地址值赋给指针变量
fmt.Println("num变量的地址为:",p)
fmt.Println("指针变量p的地址为:",&p)
fmt.Println("指针变量p所指向的内容:",*p)
}
执行结果:
num变量的地址为: 0xc042066080
指针变量p的地址为: 0xc042086018
指针变量p所指向的内容: 1
注意:p指针声明后其值为nil,这时如果获取指针p指向的地址内容,则会出错
package main
import "fmt"
func main(){
var p *int
fmt.Println("num变量的地址为:",p)
fmt.Println("指针变量p所指向的内容:",*p)
}
执行结果:
指针变量p指向的地址为: <nil>
panic: runtime error: invalid memory address or nil pointer dereference
使用指针修改值
在指针变量有实际指向的地址值后,可以通过如下格式直接修改指针所指向内存地址的内容:
*变量名 = 修改值
package main
import "fmt"
func mian(){
num := 1
var p *int = &num //将取得num的地址值赋给指针变量
fmt.Println("指针变量p所指向的内容:",*p)
*p = 10
fmt.Println("指针变量p所指向的内容:",*p)
}
执行结果:
指针变量p所指向的内容: 1
指针变量p所指向的内容: 10
在使用指针修改值时也需注意,可使用new()函数来给指针分配地址并初始化地址对应的值。
package main
import "fmt"
func mian(){
var p *int
p = new(int)
fmt.Println("指针变量p所指向的内容:",*p)
*p = 10
fmt.Println("指针变量p所指向的内容:",*p)
}
执行结果:
指针变量p所指向的内容: 0
指针变量p所指向的内容: 10