目錄
到底什麼是指標呢?
指標運算子
指針運算
首頁 後端開發 Golang go語言中指針有哪些運算

go語言中指針有哪些運算

Jan 04, 2023 am 10:30 AM
golang go語言 指針

go語言沒有指標運算。 go語言的語法上是不支援指標運算的,所有指標都在可控的一個範圍內使用;但實際上,go語言可以透過unsafe套件的Pointer()方法把指標轉換為uintptr類型的數字,來間接實現指針運算。

go語言中指針有哪些運算

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

到底什麼是指標呢?

記憶體就是一系列有序號的儲存單元,變數就是編譯器為記憶體位址分配的暱稱,那麼指標是什麼呢?

指標就是一個指向另一個記憶體位址變數的值

指標指向變數的記憶體位址,指標就像該變數值的記憶體位址一樣

我們來看一個程式碼片段

func main() {
    a := 200
    b := &a
    *b++
    fmt.Println(a)
}
登入後複製

在main 函數的第一行,我們定義了一個新的變數a ,並賦值為200。接下來我們定義了一個變數 b ,並將變數 a 的位址賦值給 b 。我們並不知道 a 的準確儲存位址,但是我們依然可以將 a 的位址儲存在變數 b 中。

go語言中指針有哪些運算

go語言中指針有哪些運算

因為Go 強類型的特性,第三行程式碼也許是最具幹擾性的了,b 包含a變數的位址,但是我們想增加儲存在a 變數中的值。

這樣我們必須取消引用 b ,而是跟隨指標由 b 引用 a。
然後我們將該值加 1 後,儲存回 b 中儲存的記憶體位址上。

最後一行印了a 的值,可以看到a 的值已經增加為了201

go語言中指針有哪些運算

go語言中指針有哪些運算

##Go語言中的函數傳參都是值拷貝,當我們想要修改某個變數的時候,我們可以建立一個指向該變數位址的指標變數

區別於C/C 中的指針,

Go語言中的指針不能偏移和運算,是安全指針

要搞清楚Go語言中的指標需要先知道3個概念:

指標位址、指標型別和指標取值

指標位址和指標型別

Go語言中的指標運算非常簡單,只需要記住兩個符號:&(取位址)和*(根據地址取值)。

每個變數在運行時都有一個位址,這個位址代表變數在記憶體中的位置。 Go語言中使用&字元放在變數前面對變數進行「取地址」操作。

取變數指標的語法如下:

ptr := &v    // v的类型为T
登入後複製

其中:

  • v:代表被取位址的變量,類型為T

  • ptr:用來接收位址的變量,ptr的型別就為*T,稱做T的指標型別。 *代表指針。

go語言中指針有哪些運算

func main() {
    a := 10
    b := &a
    fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
    fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
    fmt.Println(&b)                    // 0xc00000e018
}
登入後複製

指標運算子

1.指標運算子為左值時,我們可以更新目標物件的狀態;而為右值時則是為了取得目標的狀態。

func main() {
    x := 10
    var p *int = &x  //获取地址,保存到指针变量
    *p += 20        //用指针间接引用,并更新对象
    println(p, *p)  //输出指针所存储的地址,以及目标对象
}
登入後複製

輸出:

0xc000040780 30
登入後複製

2.指標型別支援相等運算符,但不能做加減運算和型別轉換。如果兩個指標指向同一位址,或都為nil,那麼它們相等。

func main() {
    x := 10
    p := &x

    p++   //编译报错 invalid operation: p++ (non-numeric type *int)
    var p2 *int = p+1  //invalid operation: p + 1 (mismatched types *int and int)
    p2 = &x
    println(p == p2)   //指向同一地址
}
登入後複製

可透過unsafe.Pointer將指標轉換為uintptr後進行加減法運算,但可能會造成非法存取。

指針運算

在很多golang 程式中,雖然用到了指針,但是不會對指針進行加減運算,這和C 程式是很不一樣的。 Golang 的官方入門學習工具(

go tour) 甚至說 Go 不支援指標算術。雖然實際上並不是這樣的,但我在一般的 go 程序中,好像確實沒見過指針運算(嗯,我知道你想寫不一般的程序)。

  • 但实际上,go 可以通过 unsafe.Pointer 来把指针转换为 uintptr 类型的数字,来间接实现指针运算。
  • 这里请注意,uintptr 是一种整数类型,而不是指针类型。

比如:

uintptr(unsafe.Pointer(&p)) + 1
登入後複製

就得到了 &p 的下一个字节的位置。然而,根据 《Go Programming Language》 的提示,我们最好直接把这个计算得到的内存地址转换为指针类型:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + 1))
登入後複製

因为 go 中是有垃圾回收机制的,如果某种 GC 挪动了目标值的内存地址,以整型来存储的指针数值,就成了无效的值。

同时也要注意,go 中对指针的 + 1,真的就只是指向了下一个字节,而 C 中 + 1 或者 ++ 考虑了数据类型的长度,会自动指向当前值结尾后的下一个字节(或者说,有可能就是下一个值的开始)。如果 go 中要想实现同样的效果,可以使用 unsafe.Sizeof 方法:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + unsafe.Sizeof(p)))
登入後複製

最后,另外一种常用的指针操作是转换指针类型。这也可以利用 unsafe 包来实现:

var a int64 = 1
(*int8)(unsafe.Pointer(&a))
登入後複製

如果你没有遇到过需要转换指针类型的需求,可以看看这个项目(端口扫描工具),其中构建 IP 协议首部的代码,就用到了指针类型转换。

【相关推荐:Go视频教程编程教学

以上是go語言中指針有哪些運算的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1655
14
CakePHP 教程
1414
52
Laravel 教程
1307
25
PHP教程
1253
29
C# 教程
1227
24
在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? 在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? Apr 02, 2025 pm 05:03 PM

Go編程中的資源管理:Mysql和Redis的連接與釋放在學習Go編程過程中,如何正確管理資源,特別是與數據庫和緩存�...

VSCode中如何解決Golang泛型函數類型約束被自動刪除的問題? VSCode中如何解決Golang泛型函數類型約束被自動刪除的問題? Apr 02, 2025 pm 02:15 PM

VSCode中Golang泛型函數類型約束的自動刪除問題在使用VSCode編寫Golang代碼時,用戶可能會遇到一個奇怪的問題。當...

Golang的目的:建立高效且可擴展的系統 Golang的目的:建立高效且可擴展的系統 Apr 09, 2025 pm 05:17 PM

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

See all articles