1.1 指针的概念
指针式存储另一个变量的内存地址的变量。
变量是一种使用方便的占位符,用于引用计算机内存地址。
一个指针变量可以指向任何一个值的内存地址。
1.2获取变量的地址
Go语言中的取地址符与C语言取地址符一样是&,放到一个变量前使用就会返回相应变量的内存地址。
arr := []int32{1, 2, 3}
fmt.Println(arr)
fmt.Println(&arr)
fmt.Printf("变量的地址%x\n",&arr)
a:=10
fmt.Println(a)
fmt.Println(&a)
fmt.Printf("变量的地址%x\n",&a)
/*
[1 2 3]
&[1 2 3]
变量的地址&[1 2 3]
10
0xc0000a20c0
变量的地址c0000a20c0
*/
1.3 声明指针
声明指针,*T是指针变量的类型,它指向T类型的值。
var var_name * var-type
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
示例:
var a = 10 // 声明实际变量
var ip *int // 声明指针变量
ip = &a // 注意指针类型要与变量类型相同 int与int相同,诸如int与int16,int与int32不行
fmt.Printf("a变量的地址是: %x\n", &a)
fmt.Printf("ip变量的存储地址: %x\n", ip)
fmt.Printf("*ip变量对应的值是: %d\n", *ip)
/*
a变量的地址是: c00000a100
ip变量的存储地址: c00000a100
*ip变量对应的值是: 10
*/
1.4 空指针
当一个指针被定义后,没有分配到任何变量时,它就是nil。nil指针也称为空指针。nil在概念上和其他语言的null、None、nil、NULL一样,都指代零值或者空值。一个指针变量统长缩写为ptr
空指针判断:
if(ptr != nil) // ptr不是空指针
if(ptr == nil) // ptr是空指针
示例:
var ip *int // 定义指针,但是不分配任何变量
fmt.Printf("ip变量的存储地址: %x\n", ip)
if (ip == nil) {
fmt.Println("为空指针")
} else {
fmt.Println("不是空指针")
}
/*
ip变量的存储地址: 0
为空指针
*/
1.5 获取指针对应的值
获取一个指针对应的值。语法是 *指针变量
示例:
var str = "127.0.0.1"
ip := &str
fmt.Println("ip的值是: ", ip)
fmt.Println("ip所指向的值是: ", &ip)
fmt.Println("str的类型是: ", reflect.TypeOf(str))
fmt.Println("ip的类型是: ", reflect.TypeOf(ip))
/*
ip的值是: 0xc00002c1f0
ip所指向的值是: 0xc000006030
str的类型是: string
ip的类型是: *string
*/
1.6 操作指针改变变量的数值
使用 *指针变量,获取值然后进行操作
var a = 1
b := &a
fmt.Println("a的地址是:", b)
fmt.Println("a的旧值是: ", *b)
*b++
fmt.Println("a的新值是: ", a)
fmt.Println("a的新值是: ", *b)
/*
a的地址是: 0xc00000a100
a的旧值是: 1
a的新值是: 2
a的新值是: 2
*/
将指向数组的指针作为参数传递给函数,进行修改
方法1:通过原始的方法进行修改
originArr := []int{1, 1, 3, 4, 5}
fmt.Println("originArr原始的值是: ", originArr)
modify(&originArr, 1, 2) // 将索引为1位置上的值修改为2
fmt.Println("originArr修改后的值是: ", originArr)
/*通过原始方式进行修改*/
func modify(arr *[]int, index int, newValue int) {
(*arr)[index] = newValue
}
/*
originArr原始的值是: [1 1 3 4 5]
originArr修改后的值是: [1 2 3 4 5]
*/
方法2:使用切片进行修改
originArr := []int{1, 1, 3, 4, 5}
fmt.Println("originArr原始的值是: ", originArr)
modifyBySplice(originArr[:], 1, 2) // 将索引为1位置上的值修改为2
fmt.Println("originArr修改后的值是: ", originArr)
/*通过切片进行修改*/
func modifyBySplice(arr []int, index int, newValue int) {
arr[index] = newValue
}
/*
originArr原始的值是: [1 1 3 4 5]
originArr修改后的值是: [1 2 3 4 5]
*/
1.7 指针作为函数参数
a, b := 10, 11
a, b = b, a
fmt.Println("第一次交换后:", a, b)
swap(&a, &b)
fmt.Println("第二次交换后:", a, b)
func swap(x *int, y *int) {
var temp int
temp = *x // 保存x地址的值
*x = *y
*y = temp
}
/*
第一次交换后: 11 10
第二次交换后: 10 11
*/