目錄
指針
一個指針變量指向了一個值的內存地址。類似於變量和常量,在使用指針前需要聲明、定義一個指針變量。
格式:
var var_name *var-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)
}
空指針
當一個指針變量被聲明後,卻沒有分配到任何數值時,它的值爲 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
var ptr *int
var pptr **int
a = 3000
/* 指針 ptr 地址 */
ptr = &a
/* 指向指針 ptr 地址 */
pptr = &ptr
/* 獲取 pptr 的值 */
fmt.Printf("變量 a = %d\n", a)
fmt.Printf("指針變量 *ptr = %d\n", *ptr)
fmt.Printf("指向指針的指針變量 **pptr = %d\n", **pptr)
}
甚至,還可以寫成三重指針,即:指向指針的指針的指針。
pt3 -> pto -> ptr -> 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)
}
向函數傳遞指針參數
傳入指針實參,顯然是一次引用傳遞,只需要在函數聲明的形參列表上設置爲指針類型即可。在函數調用時可以改變其值。
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
}