day07 指標

染指未来發表於2024-07-02

指標

什麼是指標

  • * 取出指標變數中的值
  • & 取地址符號
package main

import "fmt"

func main() {
	/*
		指標:
			- * 取出指標變數中的值
			- & 取地址符號

	*/

	// 1. 瞭解指標指向問題,指標取值
	var a int = 10
	// 將 a變數的記憶體地址  賦值給 b變數
	b := &a
	fmt.Printf("a 型別:%T, 地址:%p\n", a, &a) // a 型別:int, 地址:0xc000012098
	fmt.Printf("b 型別:%T, 地址:%p\n", b, &b) // b 型別:*int, 地址:0xc000058020
	fmt.Println(b)                        // 0xc00009e018

	// 透過 * 符號 獲取 b 指標變數資料。
	fmt.Println("獲取指標變數b的結果:", *b)

	// 修改指標變數b,即a變數資料也跟修改
	*b = 20
	fmt.Println("修改後的a:", a)
	fmt.Println("修改後的b:", *b)
}

指標使用

  • 定義指標變數
  • 為 指標變數賦值
  • 訪問指標變數中地址的值
package main

import "fmt"

func main() {
	/* 使用指標
	1. 定義指標變數
	2. 為 指標變數賦值
	3. 訪問指標變數中地址的值
	*/

	// 定義指標
	var a int = 10
	var ptr *int
	ptr = &a
	fmt.Printf("ptr 指標變數儲存地址:%p\n", ptr)
	fmt.Printf("ptr 指標變數自己地址:%p\n", &ptr)
	fmt.Printf("ptr 指標變數儲存地址取值:%d\n", *ptr)

	// 指標套娃
	var ptr2 **int
	ptr2 = &ptr
	fmt.Printf("ptr2 指標的指標變數儲存地址:%p\n", ptr2)
	fmt.Printf("ptr2 指標的指標變數自己地址:%p\n", &ptr2)
	fmt.Printf("ptr2 指標的指標變數儲存地址取值:%d\n", **ptr2)

	// 修改 a 變數 ptr 和 ptr2 都會修改
	a = 20
	fmt.Printf("a的值:%d\n", a)
	fmt.Printf("ptr的值:%d\n", *ptr)
	fmt.Printf("ptr2的值:%d\n", **ptr2)
	**ptr2 = 40
	fmt.Printf("a的值:%d\n", a)
	fmt.Printf("ptr的值:%d\n", *ptr)
	fmt.Printf("ptr2的值:%d\n", **ptr2)

}

指標和陣列

  • 陣列的指標`。 即:指標指向陣列變數
package main

import "fmt"

func main() {

	/* `陣列的指標`。 即:指標指向陣列變數 */
	arr := [3]int{1, 2, 3}
	fmt.Println("陣列arr:", arr)
	fmt.Printf("陣列arr記憶體地址:%p\n", &arr)

	var ptr *[3]int // 指標陣列變數
	ptr = &arr
	fmt.Printf("指標ptr儲存的陣列記憶體地址:%p\n", ptr)
	fmt.Printf("指標ptr儲存的自己記憶體地址:%p\n", &ptr)
	fmt.Printf("指標ptr儲存的陣列取值:%v\n", *ptr)

	// 透過ptr 陣列指標 修改 arr陣列資料
	(*ptr)[0] = 100
	fmt.Println(arr)

	// ptr 指向了陣列,可以直接使用ptr 運算元組。【語法糖】
	ptr[0] = 200 // ptr 指標變數指向 arr,操作ptr可以不使用 *
	fmt.Println(arr)

	/* `指標的陣列` 。 即:陣列中儲存指標的變數 */
	a := 111
	b := 222
	c := 333
	d := 444

	arr1 := [4]*int{&a, &b, &c, &d}
	fmt.Println(arr1)
	// 修改 a的值
	fmt.Println("修改 前 指標陣列:arr1 中 a變數的資料", a)
	fmt.Println("修改 前 指標陣列:arr1 中 a變數的資料", *arr1[0])
	*arr1[0] = 1000
	fmt.Println("修改 後指標陣列:arr1 中 a變數的資料", a)
	fmt.Println("修改 後指標陣列:arr1 中 a變數的資料", *arr1[0])

}

指標函式

  • 指標函式:函式的返回結果為指標型別
package main

import "fmt"

func ptrFunc() *[4]int {
	// 定一個 陣列
	ptrArr := [4]int{1, 2, 3, 4}
	return &ptrArr // 函式返回 : 陣列地址
}

func main() {
	/*指標函式:函式的返回結果為指標型別*/

	ptrFuncRes := ptrFunc()
	fmt.Println("列印函式結果:", ptrFuncRes) // 返回的是一個指標型別的變數
	fmt.Printf("指標函式結果型別:%T\n", ptrFuncRes)
	fmt.Printf("指標函式結果變數ptrFuncRes自己的地址:%p\n", &ptrFuncRes)
	fmt.Printf("指標函式結果取值:%v\n", *ptrFuncRes)

	// 修改 res 指標函式結果。 方式一透過指標:*ptrFuncRes 取出陣列修改
	fmt.Println("修改前:", (*ptrFuncRes)[0])
	fmt.Println(*ptrFuncRes)
	(*ptrFuncRes)[0] = 222
	fmt.Println("修改前:", (*ptrFuncRes)[0])
	fmt.Println(*ptrFuncRes)
	fmt.Println("-----")
	// ptrFuncRes 預設指向 陣列結果
	fmt.Println("修改前:", ptrFuncRes[0])
	fmt.Println(*ptrFuncRes)
	ptrFuncRes[0] = 333
	fmt.Println("修改前:", ptrFuncRes[0])
	fmt.Println(*ptrFuncRes)
}

指標作為函式的引數

  • 指標變數作為函式的引數
package main

import "fmt"

func updatePtrParamsFunc(ptr *int) int {
	fmt.Println("指標引數 ptr 修改前:", ptr)
	fmt.Printf("指標引數 ptr 修改前 型別:%T\n", ptr)
	fmt.Printf("指標引數 ptr 修改前 變數地址:%p\n", &ptr)
	*ptr = 100
	fmt.Println("指標引數 ptr 修改後:", ptr)
	fmt.Printf("指標引數 ptr 修改後 型別:%T\n", ptr)
	fmt.Printf("指標引數 ptr 修改後 變數地址:%p\n", &ptr)
	return *ptr
}

func updatePtrParamsFunc2(ptrArr *[3]int) {
	fmt.Println("指標引數 ptrArr 修改前:", ptrArr)
	fmt.Printf("指標引數 ptrArr 修改前 型別:%T\n", ptrArr)
	fmt.Printf("指標引數 ptrArr 修改前 變數地址:%p\n", &ptrArr)
	ptrArr[0] = 100
	fmt.Println("指標引數 ptr 修改後:", ptrArr)
	fmt.Printf("指標引數 ptr 修改後 型別:%T\n", ptrArr)
	fmt.Printf("指標引數 ptr 修改後 變數地址:%p\n", &ptrArr)
}

func main() {
	/* 指標變數作為函式的引數*/
	var num = 10
	updatePtrParamsFunc(&num)
	fmt.Println(num)

	var array = [3]int{1, 2, 3}
	updatePtrParamsFunc2(&array)
	fmt.Println(array)
}

相關文章