1. 指针
package main
import "fmt"
func main() {
/*
指针:pointer
存储了另一个变量的内存地址的变量。
*/
//1.定义一个int类型的变量
a := 10
fmt.Println("a的数值是:",a) //10
fmt.Printf("%T
",a) //int
fmt.Printf("a的地址是:%p
",&a) //0xc00008a008
//2.创建一个指针变量,用于存储变量a的地址
var p1 *int
fmt.Println(p1) //<nil>,空指针
p1 = &a //p1指向了a的内存地址
fmt.Println("p1的数值:",p1) //p1中存储的是a的地址
fmt.Printf("p1自己的地址:%p
",&p1)
fmt.Println("p1的数值,是a的地址,该地址存储的数据:",*p1)//获取指针指向的变量的数值
//3.操作变量,更改数值 ,并不会改变地址
a = 100
fmt.Println(a)
fmt.Printf("%p
",&a)
//4.通过指针,改变变量的数值
*p1 = 200
fmt.Println(a)
//5.指针的指针
var p2 **int
fmt.Println(p2)
p2 = &p1
fmt.Printf("%T,%T,%T
",a,p1,p2) //int, *int, **int
fmt.Println("p2的数值:",p2) //p1的地址
fmt.Printf("p2自己的地址:%p
",&p2)
fmt.Println("p2中存储的地址,对应的数值,就是p1的地址,对应的数据:",*p2)
fmt.Println("p2中存储的地址,对应的数值,再获取对应的数值:",**p2)
}
2. 数组指针/指针数组
package main
import "fmt"
func main() {
/*
数组指针:首先是一个指针,一个数组的地址,整个数组就是指针
*[4]Type
指针数组:首先是一个数组,存储的数据类型是指针,只有数据是指针
[4]*Type
*[5]float64,指针,一个存储了5个浮点类型数据的数组的指针
*[3]string,指针,数组的指针,存储了3个字符串
[3]*string,数组,存储了3个字符串的指针地址的数组
[5]*float64,数组,存储了5个浮点数据的地址的数组
*[5]*float64,指针,一个数组的指针,存储了5个float类型的数据的指针地址的数组的指针
*[3]*string,指针,存储了3个字符串的指针地址的数组的指针
**[4]string,指针,存储了4个字符串数据的数组的指针的指针
**[4]*string,指针,存储了4个字符串的指针地址的数组,的指针的指针
*/
//1.创建一个普通的数组
arr1 :=[4]int{1,2,3,4}
fmt.Println(arr1)
//2.创建一个指针,存储该数组的地址--->数组指针
var p1 *[4]int
p1 = &arr1
fmt.Println(p1) //&[1 2 3 4]
fmt.Printf("%p
",p1) //数组arr1的地址
fmt.Printf("%p
",&p1) //p1指针自己的地址
//3.根据数组指针,操作数组
(*p1)[0] = 100
fmt.Println(arr1) //[100 2 3 4]
p1[0] = 200 //简化写法
fmt.Println(arr1) //[200 2 3 4]
//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) //[0xc0000620c8 0xc0000620d0 0xc0000620d8 0xc0000620e0]
arr2[0] =100
fmt.Println(arr2) //[100 2 3 4]
fmt.Println(a) //1
//通过指针数组改变值
*arr3[0] = 200
fmt.Println(arr3) //[0xc0000620c8 0xc0000620d0 0xc0000620d8 0xc0000620e0]
//a被改变了
fmt.Println(a) //200
b = 1000
fmt.Println(arr2) //[100 2 3 4]
fmt.Println(arr3) //[0xc0000620c8 0xc0000620d0 0xc0000620d8 0xc0000620e0] 地址没有变,但是值变了
for i:=0;i<len(arr3);i++{
fmt.Println(*arr3[i])
//200
//1000
//3
//4
}
}
3. 函数指针/指针函数
package main
import "fmt"
func main() {
/*
函数指针:一个指针,指向了一个函数的指针。
因为go语言中,function,默认看作一个指针,没有*。
slice,map,function存储的就是数据的地址,是引用类型,那么它就是一个指针
指针函数:一个函数,该函数的返回值是一个指针。
*/
var a func()
a = fun1
a()
arr1 := fun2()
fmt.Printf("arr1的类型:%T,地址:%p,数值:%v
", arr1, &arr1, arr1)
//arr1的类型:[4]int,地址:0xc000010360,数值:[1 2 3 4]
arr2 := fun3() //arr1的类型:[4]int,地址:0xc000010360,数值:[1 2 3 4]
fmt.Printf("arr2的类型:%T,地址:%p,数值:%v
", arr2, &arr2, arr2)
//arr2的类型:*[4]int,地址:0xc000006030,数值:&[5 6 7 8]
fmt.Printf("arr2指针中存储的数组的地址:%p
", arr2)
//arr2指针中存储的数组的地址:0xc0000103e0
}
func fun3() *[4]int { //指针函数,返回值是指针
arr := [4]int{5, 6, 7, 8}
fmt.Printf("函数中arr的地址:%p
", &arr)
return &arr
}
func fun2() [4]int { //普通函数
arr := [4]int{1, 2, 3, 4}
return arr
}
func fun1() {
fmt.Println("fun1().....")
}
4. 指针作为参数
package main
import "fmt"
func main() {
/*
指针作为参数:
参数的传递:值传递,引用传递
*/
a := 10
fmt.Println("fun1()函数调用前,a:",a)
fun1(a)
fmt.Println("fun1()函数调用后,a:",a)
//fun1()函数调用前,a: 10
//fun1()函数中,num的值: 10
//fun1()函数中修改num: 100
//fun1()函数调用后,a: 10 //因为是值传递
fun2(&a)
fmt.Println("fun2()函数调用后,a:",a)
arr1 := [4]int{1,2,3,4}
//fun2()函数中,p1: 10
//fun2()函数中,修改p1: 200
//fun2()函数调用后,a: 200
fmt.Println("fun3()函数调用前:",arr1)
fun3(arr1)
fmt.Println("fun3()函数调用后:",arr1)
//fun3()函数调用前: [1 2 3 4]
//fun3()函数中数组的: [1 2 3 4]
//fun3()函数中修改数组: [100 2 3 4]
//fun3()函数调用后: [1 2 3 4] //因为是值传递
fun4(&arr1)
fmt.Println("fun4()函数调用后:",arr1)
//fun4()函数中的数组指针: &[1 2 3 4]
//fun4()函数中的数组指针: &[200 2 3 4] //地址没有变,值变了
//fun4()函数调用后: [200 2 3 4]
}
func fun4(p2 *[4]int){ // 引用传递
fmt.Println("fun4()函数中的数组指针:",p2)
p2[0] = 200
fmt.Println("fun4()函数中的数组指针:",p2)
}
func fun3(arr2 [4]int){ // 值传递
fmt.Println("fun3()函数中数组的:",arr2)
arr2[0] = 100
fmt.Println("fun3()函数中修改数组:",arr2)
}
func fun1(num int){ // 值传递
fmt.Println("fun1()函数中,num的值:",num)
num = 100
fmt.Println("fun1()函数中修改num:",num)
}
func fun2(p1 *int){ //传递的是a的地址,就是引用传递
fmt.Println("fun2()函数中,p1:",*p1)
*p1 = 200
fmt.Println("fun2()函数中,修改p1:",*p1)
}