程序媛

指针

指针定义和取值

任何程序数据载入内存后,在内存都有他们的地址,这就是指针。而为了保存一个数据在内存中的地址,我们就需要指针变量。

指针类型是不能进行偏移和运算的,指针操作只有两个:取地址(&),根据地址取值(*)。

package main

import "fmt"

func main(){
    a := 123
    fmt.Println(a,&a) //&a是获取a的内存地址
}

// 结果 123 0xc000098008 表示123这个值是存储在0xc000098008内存地址上

指针类型查看

package main

import "fmt"

func main(){
    a := 123
    fmt.Println(a,&a)
    fmt.Printf("a:%T &a:%T",a,&a)  //a:int &a:*int
}

// 结果 123 0xc000098008 表示123这个值是存储在0xc000098008内存地址上
// %T表示数据的类型
// a:int &a:*int a是int类型,而*int表示"int的指针类型"

指针取值

package main

import "fmt"

func main(){
    a := 123
    b := &a   //将a的地址赋值给b
    fmt.Println(b,&a)  //0xc000016058 0xc000016058
    fmt.Println(*b)   //123
}

// 0xc000016058 0xc000016058表示b中存储的内容就是a的地址
// 此时用*b相当于从地址中获取值 因此结果是123

总结: 取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

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

函数的指针参数

go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,则无需拷贝数据。

package main

import "fmt"

func modify1(x int){ //x只是接受了变量a的值
    x = 100           //这里的修改只是修改了局部变量的值
}

func modify2(x *int){ //x接收的是变量a的内存地址
    *x = 100          //对x地址上的值进行修改
}

func main(){
    a := 1
    modify1(a)
    fmt.Println(a) //1

    modify2(&a)
    fmt.Println(a) // 100
}

值的交换函数再看指针

package main

import "fmt"

func swap1(x,y int){    
    x,y = y,x          
}

func swap2(x,y *int)(){   
    x,y = y,x             
}

func swap3(x,y *int)(){  
    *x,*y = *y,*x        
}

func main(){
    a := 1
    b := 2
    swap1(a,b)
    fmt.Println(a,b)  

    swap2(&a,&b)
    fmt.Println(a,b)  

    swap3(&a,&b)
    fmt.Println(a,b)   
}
package main

import "fmt"

func swap1(x,y int){    // 接收的是两个值
    x,y = y,x           // 在局部对两个值进行了交换
}

func swap2(x,y *int)(){   // 接收的是两个值的地址
    x,y = y,x             // 交换了两个地址,所以此时两个地址中的元素也变化了
}

func swap3(x,y *int)(){  // 接收的是两个值的地址
    *x,*y = *y,*x        // 将两个地址中的值进行交换
}

func main(){
    a := 1
    b := 2
    swap1(a,b)
    fmt.Println(a,b)  // 1 2

    swap2(&a,&b)
    fmt.Println(a,b)  // 1 2

    swap3(&a,&b)
    fmt.Println(a,b)   // 2 1
}
结果说明

练一练

// 看代码写出打印结果
package main

import "fmt"

func swap(x,y *int)(*int,*int){ 
    x,y = y,x                   
    return x,y                   
}

func main(){
    a := 1
    b := 2
    c,d := swap(&a,&b)          
    fmt.Println(&a,&b,c,d)
    fmt.Println(*c,*d)          

    a = *c                      
    b = *d                      
    fmt.Println(a,b)            
}
package main

import "fmt"

func swap(x,y *int)(*int,*int){  // 接收的是两个值的地址
    x,y = y,x                    // 对地址进行交换
    return x,y                   // x是b的地址,y是a的地址
}

func main(){
    a := 1
    b := 2
    c,d := swap(&a,&b)          // c指向b的地址,d指向a的地址
    fmt.Println(&a,&b,c,d)
    fmt.Println(*c,*d)          // 2 1

    a = *c                      //在a的地址中写一个c的值2
    b = *d                      //在b的地址中写一个d的值,而d和a指向同一块地址,因此b的内存中也是2
    fmt.Println(a,b)            // 2 2
}
结果说明

 

posted @ 2019-11-25 18:51  Eva_J  阅读(115)  评论(0)    收藏  举报