go 指針類型

變量和內存地址

每一個變量都有內存地址,能夠說經過變量來操做對應大小的內存數組

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

經過&符號能夠獲取變量的地址spa

 

普通變量存儲的是對應類型的值,這些類型就叫值類型

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)
    }
}    

若是操做指針變量指向的地址裏面的值呢?

 經過* 符號能夠獲取指針變量指向的變量code

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)
}

 

舉例blog

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以及channelit

new用來分配除引用類型的全部其餘類型的內存,好比 int、數組等io

 

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()
}

 

值拷貝和引用拷貝

值拷貝function

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()
}

 

練習 交換兩個變量的值class

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
    */
}
相關文章
相關標籤/搜索