指针






package main
import "fmt"
//29
func main() {
/*
指针pointer
存储了另一个变量的内存地址的变量
*/
//定义一个int类型变量
a := 10
fmt.Printf("a的地址是:%p\n",&a) //a的地址是:0xc00000a0c8
//2. 创建一个指针变量,用于存储变量a的地址
var p1 *int
fmt.Println(p1) //<nil>
p1 = &a //p1指向a的内存地址
fmt.Println("p1的数值:",p1) //p1的数值: 0xc00000a0c8
fmt.Printf("p1自己的地址:%p\n",&p1) //p1自己的地址:0xc000006030
fmt.Println("p1的数值,是a的地址,该地址存储的数据为:", *p1) //10
//操作变量,更改数值
a = 100
fmt.Println(a) //100
fmt.Printf("%p\n",&a) //0xc00000a0c8
//4. 通过指针,改变变量的数值
*p1 = 200
fmt.Println(a) //200
//5. 指针的指针
var p2 **int
fmt.Println(p2) //<nil>
p2 = &p1
fmt.Printf("%T,%T,%T",a,p1,p2) //int,*int,**int
fmt.Println("p2的数值:",p2) //0xc000006030
fmt.Println("p2的地址:",&p2) //0xc000006038
fmt.Println("a的值:",**p2) //200
fmt.Println("p1的数值:",*p2) //0xc00000a0c8
fmt.Printf("a的地址:%p\n",&a) //0xc00000a0c8 二者相同
}

数组指针和指针数组
package main
import "fmt"
//30
func main() {
/*
数组指针和指针数组
数组指针
*[4]Type
指针数组
[4]*Type
*/
//1. 创建数组
arr1 := [4]int{1,2,3,4}
fmt.Println(arr1) //[1 2 3 4]
//2. 创建一个指针,存储该数组的地址:数组指针
var p1 *[4]int
p1 = &arr1
fmt.Println(p1) //&[1 2 3 4]
fmt.Printf("%p\n",p1) //0xc000110020
fmt.Printf("%p\n",&p1) //0xc000104020
//3. 根据数组指针,操作数组
(*p1)[0] = 100
fmt.Println(arr1) //[100 2 3 4]
//简化写法
p1[0] = 200
fmt.Println(arr1) //[200 2 3 4]
//指针数组
a := 1
b := 2
c := 3
d := 4
arr2 := [4]int{a,b,c,d}
arr3 := [4]*int{&a,&b,&c,&d}
fmt.Println(arr2) //[1 2 3 4]
fmt.Println(arr3) //[0xc00000a120 0xc00000a128 0xc00000a130 0xc00000a138]
arr2[0] = 100
fmt.Println(arr2) //[100 2 3 4]
fmt.Println(a) //1 变量a并未改变
*arr3[0] = 200
fmt.Println(arr3) //[0xc00000a120 0xc00000a128 0xc00000a130 0xc00000a138]
fmt.Println(a) //200
b = 1000
fmt.Println(arr2) //值无改变,值传递 [100 2 3 4]
fmt.Println(arr3) //地址无改变 [0xc00000a120 0xc00000a128 0xc00000a130 0xc00000a138]
}

函数指针和指针函数
package main
import "fmt"
//31
func main() {
/*
函数指针和指针函数
函数指针:一个指针,指向了一个函数的指针
因为go语言中,function默认看作一个指针,没有*
slice,map,function
指针函数:一个函数。该函数的返回值是一个指针
*/
//函数指针
var a func()
a = funa
a() //funa()...
//指针函数
arr1 := funb()
//arr1的类型:[4]int,地址:0xc000012380,数值:[1 2 3 4]
fmt.Printf("arr1的类型:%T,地址:%p,数值:%v\n",arr1,&arr1,arr1)
arr2 := fund()
//arr2的类型:*[4]int,地址:0xc000006030,数值:&[1 2 3 4]
fmt.Printf("arr2的类型:%T,地址:%p,数值:%v\n",arr2,&arr2,arr2)
fmt.Printf("arr2指针中存储的数组的地址:%p\n",arr2)//arr2指针中存储的数组的地址:0xc000012400
}
func fund()*[4]int {
arr := [4]int{1,2,3,4}
fmt.Printf("函数中arr的地址:%p\n",&arr) //函数中arr的地址:0xc000012400
return &arr
}
func funb()[4]int {
arr := [4]int{1,2,3,4}
return arr
}
func funa() {
fmt.Println("funa()...")
}

指针作为参数
package main
import "fmt"
//32
func main() {
/*
指针作为参数
参数的传递:
值传递、引用传递
*/
a := 10
fmt.Println("fun111()函数调用前a:",a) //fun111()函数调用前a: 10
fun111(a)
fmt.Println("fun111()函数调用后a:",a) //fun111()函数调用后a: 10
fun222(&a)
fmt.Println("fun2()函数调用后a:",a) //fun2()函数调用后a: 200
}
func fun222(p1 *int) {
fmt.Println("fun222()函数中p1:",*p1) //fun222()函数中p1: 10
*p1 = 200
fmt.Println("fun222()函数中,修改后p1:",*p1) //fun222()函数中,修改后p1: 200
}
func fun111(num int) {
fmt.Println("fun111()函数中的num值:",num) //fun111()函数中的num值: 10
num = 100
fmt.Println("fun111()函数中修改后的num值:",num) //fun111()函数中修改后的num值: 100
}

指针多用于处理值传递,减少值复制耗费的内存
网友评论