目錄
文章目錄
- 指針
- 空指針
- 雙重指針
- 向函數傳遞指針參數
指針
一個指針變量指向了一個值的記憶體位址。類似于變量和常量,在使用指針前需要聲明、定義一個指針變量。
聲明一個指針變量,格式:
var var_name *type
示例:
var ip *int /* 聲明整型指針變量 */
var fp *float32 /* 聲明浮點型指針變量 */
指針使用流程:
- 聲明指針變量。
- 為指針變量指派。
- 通路指針變量中指向位址的值。
package main
import "fmt"
func main() {
var a int = 20
var ip *int
ip = &a
fmt.Printf("a 變量的記憶體位址是: %x\n", &a)
fmt.Printf("ip 變量儲存的指針位址是: %x\n", ip)
/* 使用指針通路資料值 */
fmt.Printf("*ip 變量的值: %d\n", *ip)
}
結果:
a 變量的記憶體位址是: c0000b4008
ip 變量儲存的指針位址是: c0000b4008
*ip 變量的值: 20
空指針
當一個指針變量被聲明後,卻沒有配置設定到任何數值時,它的值為 nil(空)。nil 在概念上和其它語言的 null、None、nil、NULL 一樣,都指代零值或空值。
package main
import "fmt"
func main() {
var ptr *int
fmt.Printf("ptr 的值為 : %x\n", ptr)
}
ptr 的值為 : 0
空指針判斷:
if(ptr != nil) /* ptr 不是空指針 */
if(ptr == nil) /* ptr 是空指針 */
雙重指針
雙重指針,即指向指針的指針。
var ptr **int;
package main
import "fmt"
func main() {
var a int = 3000
var ptr *int
var pptr **int
ptr = &a
pptr = &ptr
fmt.Printf("變量 a = %d\n", a)
fmt.Printf("指針變量 *ptr = %d\n", *ptr)
fmt.Printf("指向指針的指針變量 **pptr = %d\n", **pptr)
}
變量 a = 3000
指針變量 *ptr = 3000
指向指針的指針變量 **pptr = 3000
甚至,還可以寫成三重指針,即:指向指針的指針的指針。
ptr3 -> ptr2e -> ptr1 -> a
package main
import "fmt"
func main() {
var a int = 1
var ptr1 *int = &a
var ptr2 **int = &ptr1
var ptr3 ***int = &ptr2
// 依次類推
fmt.Println("a:", a)
fmt.Println("ptr1", ptr1)
fmt.Println("ptr2", ptr2)
fmt.Println("ptr3", ptr3)
fmt.Println("*ptr1", *ptr1)
fmt.Println("**ptr2", **ptr2)
fmt.Println("***ptr3", ***ptr3)
}
a: 1
ptr1 0xc00012c008
ptr2 0xc000124018
ptr3 0xc000124020
*ptr1 1
**ptr2 1
***ptr3 1
package main
import "fmt"
func main() {
var a int = 100
var b int= 200
swap(&a, &b);
fmt.Printf("交換後 a 的值 : %d\n", a)
fmt.Printf("交換後 b 的值 : %d\n", b)
}
/* 交換函數這樣寫更加簡潔,也是 Golang 的特性 */
func swap(x *int, y *int){
*x, *y = *y, *x
}
交換後 a 的值 : 200
交換後 b 的值 : 100