日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang——指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针

發布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang——指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

指針:

  • 指針是一個特殊的變量,因為存儲的數據不僅僅是一個普通的數據,而是一個變量的內存地址,指針本身也是有內存地址的
  • 指針的數據類型有int、float、bool、string、數組、結構體
  • 指針的作用就是可以通過變量/對象的內存地址去操作變量/對象
  • 并非所有對象都能進行取地址操作,但變量總是能正確返回(addressable)。指針運算符為左值時,我們可更新目標對象狀態,而為右值時則是為了獲取目標狀態。

注意:

  • 空指針:未初始化的指針 使用*p獲取
  • 野指針:被無效地址空間初始化
  • 取址運算符&用于獲取對象地址
  • 指針運算符*用于間接引用目標對象
  • 二級指針(一個指針指向另一個指針)**T,或包含包名*package.T

指針定義:

定義格式:

var 指針名 *類型

獲取內存地址格式:

&變量/指針

通過指針修改變量的值:

// *指針變量是獲取到內存地址指向的變量值,拿到后可以再修改,或者其它操作 *指針變量 =

演示:

func pointerDemo01() {a := 10// 定義一個指針變量p,并把a的內存地址賦值給pvar p *int// &可以獲取內存地址p = &a// 對比a的內存地址和p變量存的數據是一樣的fmt.Println("變量a的內存地址:", &a)fmt.Println("指針p的數據:", p)fmt.Println("指針p存的數據:", *p)fmt.Println("指針p的內存地址:", &p)// 通過指針修改數據,a的數據也同步修改*p = 222fmt.Println(a) }

指針類型支持相等運算符,但不能做加減法運算和直接類型轉換。如果兩個指針指向同一地址,或都為nil,那么它們相等

func main() {x := 10p := &xp++ // 無效運算:p++ (non-numeric type *int)var p2 *int = p + 1 // 無效運算: p + 1 (mismatched types *int and int)p2 = &xprintln(p == p2) }

零長度(zero-size)對象的地址是否相等和具體的實現版本有關,不過肯定不等于nil

即便長度為0,可該對象依然是合法存在的,也擁有內存地址,這與nil語義完全不同。
在runtime/malloc.go里有個zerobase全局變量,所有通過mallocgc分配的零長度對象都使用該地址。不過下例中,對象a、b在棧上分配,并未調用mallocgc函數

func main() {var a, b struct{}println(&a, &b)println(&a == &b, &a == nil) }

打印結果:

0x14000096f68 0x14000096f68 false false

操作指針的3個注意事項:

  • 空指針
  • var p *intfmt.Println(p) // <nil>
  • 不要操作沒有合法指向的內存
  • var p *int*p = 111fmt.Println(p) // invalid memory address or nil pointer dereference// 這里雖然定義了指針并賦值,但是并沒有將指針指向任何有效的變量
  • new函數使用
  • // 創建了一個int類型的內存空間,然后讓p指向內存空間,然后把222保存到了內存空間中p = new(int)*p = 222fmt.Println(*p)

    指針作為函數參數:

    在函數中修改變量值,是不影響原來的變量的,可以通過指針去修改
    不通過指針的時候,修改原來的變量,雖然變量都是a,但是內存地址是不一樣的,所以在函數中修改完以后會發現原來的變量并沒有被修改,但是通過指針去修改的時候是因為指向的是內存地址,所以對函數中的a進行操作,其實就是對原來的a進行操作,所以可以將原來的變量值修改掉

    演示:

    func main() {a := 10pointerDemo03(&a)fmt.Println(a) }// 注意,指針作為函數的時候,參數也要加上* func pointerDemo03(a *int) {*a = 20 }

    數組指針:

    要分清指針數組和數組指針的區別。指針數組是指元素為指針類型的數組,數組指針是獲取數組變量的地址

    var 數組指針變量 *[索引] 類型

    演示:

    func pointerDemo05() {arr := [10]int{1, 2, 3, 3, 4, 5}var p *[10]intp = &arrfmt.Println(*p) // 獲取數組中的全部數據fmt.Println((*p)[0]) // 獲取指定數組中索引的數據,因為*p是先運算,所以要先加括號,否則編譯保存fmt.Println(p[0]) // 獲取指定數組中索引的數據,這個格式和加括號一樣,但是簡化的寫法for i := 0; i < len(p); i++ {fmt.Print(p[i], ",")} }

    數組作為函數參數:

    func main() {arr := [10]int{1, 2, 3, 3, 4, 5}var p *[10]intp = &arrpointerDemo06(p) }func pointerDemo06(p *[10]int) {p[0] = 111fmt.Println(p) }

    指針數組:

    指針數組指的是元素為指針類型的數組(一個數組中存儲的都是指針),它就是一個存儲了地址的數組。

    定義格式:

    var 數組名 [索引] *類型

    演示:

    func pointerDemo07() {var p [2]*inta := 10b := 20// 變量a的內存地址保存在指針數組p的0索引,b保存在1索引p[0] = &ap[1] = &bfmt.Println(p) // 獲取p數組中的內存地址fmt.Println(*p[0], *p[1]) // 獲取p數組中的指定索引數據for i := 0; i < len(p); i++ {fmt.Println(*p[i]) // 獲取p數組中的所有的數據}for key, value := range p {fmt.Println(key, *value)} }

    指針與切片:

    其實就是定義指針,指向切片

    演示:

    func pointerDemo08() {s := []int{1, 2, 3, 4, 5}var p *[]intp = &sfmt.Println(*p)fmt.Println((*p)[0]) // 指針切片中沒有簡化的寫法,只能加括號先運算指針,再運算切片for i := 0; i < len(*p); i++ {fmt.Print("fori方式:", (*p)[i], ",")}for key, value := range *p {fmt.Println("range方式:", key, value)} }

    指針與結構體:

    其實就是定義指針,指向結構體

    演示:

    type Student struct {// 成員名稱不加var關鍵字id intname stringage intaddr string }func pointerDemo09() {stu := Student{001, "itzhuzhu", 23, "廣州"}var p *Studentp = &stufmt.Println(*p) // 獲取全部fmt.Println((*p).name) // 獲取指定的數據fmt.Println(p.name) // 結構體指針中也是有簡化寫法的p.addr = "深圳"fmt.Println(*p) }

    將結構體指針作為函數參數:

    func main() {stu := Student{001, "itzhuzhu", 23, "廣州"}var p *Studentp = &stupointerDemo10(p)fmt.Println(stu) }```go func pointerDemo10(p *Student) {p.addr = "深圳" }

    多級指針:

    多級指針指的是,存放的都是上一級指針的內存地址,二級指針存的是一級指針的內存地址,以此類推,多級指針的概念和二維數組的概念類似。多級指針可以無限定義級別,幾級指針定義的時候就要寫幾個*

    定義格式:

    var 指針變量名 *類型 // 幾級指針就寫幾個* 一個* 就是一級指針

    演示:

    func pointerDemo11() {a := 10var p *intp = &a// 定義二級指針,var p2 **int//var p3 ***int//var p4 ****intp2 = &pfmt.Println(**p2) // 10 }

    總結

    以上是生活随笔為你收集整理的Golang——指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。