GO指针

指针和地址的区别

地址:内存地址(用字节来描述的内存地址)
指针:指针是带类型的,int类型指针与string类型指针是完全不同的!指针是存储另一个变量内存地址的变量。

&和*

&:取内存地址
*:根据地址来取值

对变量进行取地址(&)操作,可以获得这个变量的指针变量。
指针变量的值是指针地址。
对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。

声明指针

*T是指针变量的类型,指向T类型的指针

var ptr *ptr

指针地址和指针类型

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。
取变量指针地址:

ptr := &v

v:代表被取地址的变量,类型为T
ptr:用于接收地址的变量,ptr的类型就为T,称做T的指针类型。代表指针。

a := 1
b := &a //取a的内存地址,将指针保存在b中
fmt.Printf("a的值是%d,a的内存地址是%p\n",a,&a)   //a的值是1,a的内存地址是0xc420080050
fmt.Println(b,*b)   //0xc420080050 1
fmt.Printf("%T\n",b)    //b是int类型的指针  *int

指针取值

指针使用*操作,可以取到指针的值。

fmt.Println(b,*b)   //0xc420080050 1

指针传值

func modify1(x int)  {
    x = 100 //只是修改内部的x的值,值传递
}
//接受的参数是一个指针
func modify2(x *int)  {
    *x = 100    //传参的时候想要修改传入的参数,需要使用指针,引用传递
}

func main()  {
    a := 10
    modify1(a)      //在函数中复制了变量a赋值给了内部的x
    fmt.Println(a)  //10
    modify2(&a)
    fmt.Println(a)  //100
}

数组指针和指针数组

数组指针:一个指针,一个数组的地址.*[n]type

func main() {
    arr1 := [4]int{1, 2, 3, 4}
    //创建一个指针,存储该数组的地址--->数组指针
    var p1 *[4]int
    p1 = &arr1
    fmt.Println(p1)         //&[1 2 3 4]
    fmt.Printf("%p\n", p1)  //数组arr1的内存地址0xc000092000
    fmt.Printf("%p\n", &p1) //p1指针的内存地址0xc00008c010
    //根据数组指针操作数组
    (*p1)[0] = 100
    fmt.Println(arr1) //[100 2 3 4]
    //简化写法
    p1[1] = 200
    fmt.Println(arr1) //[100 200 3 4]
}

指针数组:一个数组,存储的数据类型是指针[n]*type

func main() {
    //指针数组
    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) //[0xc000016080 0xc000016088 0xc000016090 0xc000016098]
    arr2[1] = 100     //修改数组中元素的值
    fmt.Println(arr2) //[1 100 3 4]
    fmt.Println(b)    //2 并没有操作变量的值,所以变量值不变
    *arr3[0] = 100
    fmt.Println(arr3) //[0xc000016080 0xc000016088 0xc000016090 0xc000016098] 内存地址没有改变
    for _, v := range arr3 {
        fmt.Println(*v)
    }
    fmt.Println(a) //100  操作的是变量的内存地址所对应的数据,所以变量值发生改变
}

new()函数创建指针

new()用来做指针的初始化。
语法:

new(T)

EGG:

var a = new(int)    //得到一个int类型的指针
fmt.Println(a)  //0xc42000e228
*a = 10 //根据内存地址赋值成10
fmt.Println(a)  //0xc42000e228
fmt.Println(*a) //10
//值类型的都可以用new初始化,得到一个指针
var b = new([3]int)
fmt.Println(b)  //&[0 0 0]
b[0] = 10       //等同于(*b)[0] = 10
fmt.Println(*b) //[10 0 0]
posted @ 2019-04-16 22:18  我是一条最咸的咸鱼  阅读(551)  评论(0编辑  收藏  举报
返回顶部