go 指针类型

变量和内存地址

每个变量都有内存地址,可以说通过变量来操作对应大小的内存

var a int32
a = 100
fmt.Printf(“%d\n”, a)
fmt.Printf(“%p\n”, &a)

通过&符号可以获取变量的地址

 

普通变量存储的是对应类型的值,这些类型就叫值类型

var b int32
b = 156
fmt.Printf(“%d\n”, b)
fmt.Printf(“%p\n”, &b)

 

指针类型的变量存储的是一个地址,所以有叫指针类型或引用类型

var b int32
b = 156
var a *int32
a = &b

 

 

 指针类型定义,var 变量名 *类型

package main
import ( 
    "fmt"
)
func main() { 
    b := 255
    var a *int = &b
    fmt.Printf("Type of a is %T\n", a)
    fmt.Println("address of b is", a)
}

指针类型变量的默认值为nil,也就是空地址

package main
import ( 
 "fmt"
)
func main() { 
    a := 25
    var b *int
    if b == nil {
        fmt.Println("b is", b)
        b = &a
        fmt.Println("b after initialization is", b)
    }
}    

如果操作指针变量指向的地址里面的值呢?

 通过* 符号可以获取指针变量指向的变量

package main 
import ( 
 "fmt"
)
func main() { 
  b := 255
  a := &b
  fmt.Println("address of b is", a)
  fmt.Println("value of b is",*a)
}

 通过指针修改变量的值

package main
import ( 
 "fmt"
)
func main() { 
   b := 255
   a := &b
   fmt.Println("address of b is", a)
   fmt.Println("value of b is",*a)
   *a++
   fmt.Println("new value of b is", b)
}

 

举例

package main

import "fmt"

// 定义指针
func test1() {
    var a int = 100
    var b *int
    fmt.Printf("a 的值为: %v  a的内存地址是:%p  a的类型是%t\n", a, &a, a)
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, &b, b)

    b = &a
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, &b, b)
}

/*
a 的值为: 100  a的内存地址是:%!p(int=100)  a的类型是%!t(int=100)
b 的值为: <nil>  b的内存地址是:0x0  b的类型是%!t(*int=<nil>)
b 的值为: 0xc0000100a8  b的内存地址是:0xc0000100a8  b的类型是%!t(*int=0xc0000100a8)
*/

//控指针
func test2() {
    var a int = 100
    var b *int
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, &b, b)
    if b == nil {
        fmt.Println("b是一个空指针")
        b = &a
    }
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, &b, b)
}

/*
b 的值为: <nil>  b的内存地址是:0xc000080018  b的类型是%!t(*int=<nil>)
b是一个空指针
b 的值为: 0xc000058080  b的内存地址是:0xc000080018  b的类型是%!t(*int=0xc000058080)
*/

// 获取指针对应地址的值
func test3() {
    var a int = 100
    var b *int
    b = &a
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, &b, b)
    fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)

}

/*
b 的值为: 0xc0000100a8  b的内存地址是:0xc000006028  b的类型是%!t(*int=0xc0000100a8)
b 中存储的内存地址对应的值为100
*/

// 改变指针存储地址对应的值
func test4() {
    var a int = 100
    var b *int
    b = &a
    fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
    fmt.Printf("a的值为%v\n", a)
    *b = 500
    fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
    fmt.Printf("a的值为%v\n", a)

}

/*
b 中存储的内存地址对应的值为100
a的值为100
b 中存储的内存地址对应的值为500
a的值为500
*/

func main() {
    // test1()
    // test2()
    test3()
    // test4()
}

指针变量传参

package main
import ( 
 "fmt"
)
func change(val *int) { 
  *val = 55
}
func main() { a :
= 58 fmt.Println("value of a before function call is",a) b := &a change(b) fmt.Println("value of a after function call is", a) }

 

package main
import ( 
 "fmt"
)
func modify(arr *[3]int) { 
  (*arr)[0] = 90
}
func main() { 
  a := [3]int{89, 90, 91}
  modify(&a)
  fmt.Println(a)
}

切片传参  切片是应用类型

package main
import ( 
 "fmt"
)
func modify(sls []int) { 
  sls[0] = 90
}
func main() { 
  a := [3]int{89, 90, 91}
  modify(a[:])
  fmt.Println(a)
}

 

 

package main

import "fmt"

func test1() {
    var a int = 100
    var b *int
    b = &a
    fmt.Printf("a 的值为: %v  a的内存地址是:%p  a的类型是%t\n", a, a, a)
    fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, b, b)

    a = 200
    fmt.Printf("a 的值为: %v  a的内存地址是:%p  a的类型是%t\n", a, a, a)
    fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
    fmt.Printf("b 的值为: %v  b的内存地址是:%p  b的类型是%t\n", b, b, b)

}

/*
a 的值为: 100  a的内存地址是:%!p(int=100)  a的类型是%!t(int=100)
b 中存储的内存地址对应的值为100
b 的值为: 0xc000058080  b的内存地址是:0xc000058080  b的类型是%!t(*int=0xc000058080)
a 的值为: 200  a的内存地址是:%!p(int=200)  a的类型是%!t(int=200)
b 中存储的内存地址对应的值为200
b 的值为: 0xc000058080  b的内存地址是:0xc000058080  b的类型是%!t(*int=0xc000058080)
*/

func test2(a *int) {
    *a = 200
}

func test3(a *[3]int) {
    (*a)[0] = 1000
}

func test4(a []int){
    a[0] = 123

}

func modifytest() {
    // var a int = 2
    // test2(&a)
    // fmt.Printf("修改后a的值为 %d", a) //修改后a的值为 200

    // a := [3]int{1, 2, 3}
    // test3(&a)
    // fmt.Printf("修改后a的值为 %v", a) // 修改后a的值为 [1000 2 3]


    a:= [5]int{1,5,6,4,5}
    test4(a[:])
    fmt.Printf("修改后a的值为 %v", a) // 修改后a的值为 [123 5 6 4 5]
}

func main() {
    // test1()

    modifytest()
}

 

make 和 new

make用来分配引用类型的内存,比如 map、slice以及channel

new用来分配除引用类型的所有其他类型的内存,比如 int、数组等

 

package main

import "fmt"

func testNew() {
    var a *int = new(int)
    *a = 100
    fmt.Printf("a=%v, a的内存地址%p, *a= v%  *a的内存地址%p\n", a, a, *a, &(*a))

    var b *[]int = new([]int)
    *b = make([]int, 5, 10)
    (*b)[0] = 10
    fmt.Printf("b=%v, b的内存地址%p, *b= v%  *b的内存地址%p\n", b, b, *b, &(*b))
}

func main() {
    testNew()
}

 

值拷贝和引用拷贝

值拷贝

package main
import ( 
  "fmt"
)
func main() { 
  var a int = 100
  b := a
}

 

引用拷贝

package main
import ( 
  "fmt"
)
func main() { 
  var a int = 100
  var b *int = &a
  var c *int = b
  *c = 200
}

package main

import "fmt"

// 值拷贝
func test1() {
    var a int = 100
    b := a
    fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
    fmt.Printf("b= %d, b的内存地址为%p\n", b, &b)

}

/*
a= 100, a的内存地址为0xc000058080
b= 100, b的内存地址为0xc000058088
*/

// 引用拷贝
func test2() {
    var a int = 10
    var b *int
    b = &a
    fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
    fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b)

    *b = 100
    fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
    fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b)
}

/*
a= 10, a的内存地址为0xc000058080
b= 0xc000058080, b的内存地址为0xc000080018 *b=10
a= 100, a的内存地址为0xc000058080
b= 0xc000058080, b的内存地址为0xc000080018 *b=100
*/

func test3() {
    var a [3]int = [3]int{1, 2, 3}
    var b *[3]int

    b = &a

    fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
    fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b)

    (*b)[1] = 100
    fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
    fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b)
    
    
}
/*
a= [1 2 3], a的内存地址为0xc0000560c0
b= &[1 2 3], b的内存地址为0xc000080018 *b=[1 2 3]
a= [1 100 3], a的内存地址为0xc0000560c0
b= &[1 100 3], b的内存地址为0xc000080018 *b=[1 100 3]
*/


func main() {
    // test1()
    // test2()
    test3()
}

 

练习 交换两个变量的值

package main

import "fmt"

func swap1(a int, b int) {
    fmt.Printf("swap  交换前 a= %d b=%d\n", a, b)
    a, b = b, a
    fmt.Printf("swap  交换后 a= %d b=%d\n", a, b)
}

func swap2(a *int, b *int) {
    fmt.Printf("swap  交换前 a= %d b=%d\n", *a, *b)
    *a, *b = *b, *a
    fmt.Printf("swap  交换后 a= %d b=%d\n", *a, *b)
}

func main() {
    var a int = 10
    var b int = 20
    // fmt.Printf("main  交换前 a= %d b=%d\n", a, b)
    // swap1(a, b)
    // fmt.Printf("main  交换后 a= %d b=%d\n", a, b)

    /*
        main  交换前 a= 10 b=20
        swap  交换前 a= 10 b=20
        swap  交换后 a= 20 b=10
        main  交换后 a= 10 b=20
    */

    var c *int
    var d *int

    c = &a
    d = &b
    
    fmt.Printf("main  交换前 a= %d b=%d\n", a, b)
    swap2(c, d)
    fmt.Printf("main  交换后 a= %d b=%d\n", a, b)

    /*
    main  交换前 a= 10 b=20
    swap  交换前 a= 10 b=20
    swap  交换后 a= 20 b=10
    main  交换后 a= 20 b=10
    */
}

 

posted @ 2019-01-27 22:13  A-a  阅读(2127)  评论(1编辑  收藏  举报