指標
什麼是指標
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)
}