每一個變量都有內存地址,能夠說經過變量來操做對應大小的內存數組
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
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用來分配引用類型的內存,好比 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 */ }