Go學習隨筆(五)指針\指針的指針\指針數組\指針傳遞函數

大家都知道所有的指針變量都是一個內存位置,每個內存位置都有其定義的地址,可以使用&運算符來訪問它,這個運算符表示內存中的地址。

func main() {
	a := 10
	fmt.Printf("%x\n", &a) //打印變量a的地址
	
返回:c0000140a8
}

指針概念:指針是一個變量,其值是另一個變量的地址,即存儲器位置的直接地址。

 Go語言使用 * 運算符來取得指向指針存儲的內存地址所對應的值(指針的格式化爲%p),Go語言指針不支持運算,也不支持     -> 運算符,可以直接用,訪問目標成員(有涉及到struct以後再寫)

func main() {
	a := 10
	ip := &a
	value := *ip
	fmt.Printf("a的地址:%x\n", &a)
	fmt.Printf("ip的地址:%x\n", &ip)
	fmt.Printf("ip的值:%d\n", *ip)
	fmt.Printf("value的值:%d", value)
}

結果:
a的地址:c0000140a8
ip的地址:c000006028
ip的值:10
value的值:10

nil指針

當一個指針被定義後沒有分配到任何變量時,它的默認值爲 nil。指針變量通常縮寫爲 ptr。nil指針是在幾個標準庫中定義的值爲零的常量。

注意:對一個空指針的方向引用是不合法的,並會使程序奔潰。(var p *int = nil; *p = 10)

 

func main() {
	var ptr *int
	fmt.Printf("prt的值是:%x\n", ptr)
	if ptr != nil {
		fmt.Println("非空")
	} else {
		fmt.Println("空")
	}
}

prt的值是:0
空

指針的指針

func main() {
	var a *int //定義一個a指針,指向nil
	aP := &a   //空指針a的指針
	fmt.Printf("a-->nil:%x\n", a)
	fmt.Printf("a指針的內存地址:%x\n", &a)
	fmt.Printf("aP-->a:%x\n", aP)
	fmt.Printf("aP-->a-->nil(指針aP指向的指針a的內存地址):%x\n", *aP)
}

結果:
a-->nil:0
a指針的內存地址:c000006028
aP-->a:c000006028
aP-->a-->nil(指針aP指向的指針a的內存地址):0

如果定義一個指針的指針,可以這樣定義:var ptr **int;

 

func main() {
	a := 10
	aP := &a
	aPP := &aP
	fmt.Printf("a:%d\n", a)
	fmt.Printf("aP:%x\n", aP)
	fmt.Printf("*aP:%d\n", *aP)
	fmt.Printf("aPP:%x\n", aPP)
	fmt.Printf("*aPP:%x\n", *aPP)
	fmt.Printf("**aPP:%d\n", **aPP)
}

結果:
a:10
aP:c0000140a8        //ap是a的內存地址
*aP:10              
aPP:c000006028       //app是ap的內存地址
*aPP:c0000140a8   //這裏的是ap的地址
**aPP:10            //這才能拿到a的值

 

提醒各位一句:禁止套娃!!!

 指針數組

 指向數組的指針也會有多個值,確切說是指針數組有多個值

const MAX int = 3

//使用三個整數,將他們存儲在指針數組中
func main() {
	a := []int{10, 100, 200} //初始化a數組
	var ptr [MAX]*int        //這裏將ptr聲明爲一個指針數組,數組長度爲MAX,ptr中的每個元素現在保存一個指向int值的指針
	for i := 0; i < MAX; i++ {
		ptr[i] = &a[i]
		fmt.Printf("a[%d]的地址:%x\n", i, ptr[i])
	}

	for i := 0; i < MAX; i++ {
		fmt.Printf("a[%d]的值是:%d\n", i, *ptr[i])
	}
}

結果:
a[0]的地址:c00007e120
a[1]的地址:c00007e128
a[2]的地址:c00007e130
a[0]的值是:10
a[1]的值是:100
a[2]的值是:200

指針傳遞給函數

func main() {
	a := 100
	b := 200

	fmt.Printf("交換之前a的值爲:%d\n", a)
	fmt.Printf("交換之前b的值爲:%d\n", b)

	//把a和b的地址傳遞給函數,然後a和b的地址交換,最終實現兩個值交換
	swap(&a, &b)

	fmt.Printf("交換之後的a值爲:%d\n", a)
	fmt.Printf("交換之後的b值爲:%d\n", b)
}

func swap(x *int, y *int) {
	fmt.Printf("原a的地址:%x\n", &x)
	fmt.Printf("原b的地址:%x\n", &y)
	fmt.Printf("原a:%d\n", *x)
	fmt.Printf("原b:%d\n", *y)
	var temp int
	temp = *x
	*x = *y
	*y = temp
}

結果:
交換之前a的值爲:100
交換之前b的值爲:200
原a的地址:c00009e020
原b的地址:c00009e028
原a:100
原b:200
交換之後的a值爲:200
交換之後的b值爲:100

 

發佈了60 篇原創文章 · 獲贊 34 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章