go語言中的數(shù)組指針和指針數(shù)組的區(qū)別小結(jié)
1.介紹
大家知道C語言之所以強(qiáng)大,就是因?yàn)閏語言支持指針,而且權(quán)限特別大,c語言可以對(duì)計(jì)算機(jī)中任何內(nèi)存的指針進(jìn)行操作,這樣自然而然也會(huì)帶來一些不安全的因素,所以在golang中,「取消了對(duì)指針的一些偏移,翻轉(zhuǎn)等算術(shù)運(yùn)算」(+、-、++、--)所以使用起來更安全。
- 數(shù)組指針 :它是一個(gè)指針,但是數(shù)據(jù)類型為數(shù)組,或者說指向數(shù)組
- 指針數(shù)組 :它是一個(gè)數(shù)組,該數(shù)組的元素都為地址值
2.數(shù)組指針
在Go語言中,數(shù)組是一個(gè)固定長度的相同類型元素的序列。數(shù)組在聲明時(shí)必須指定其長度,并且一旦創(chuàng)建,其長度就不能改變。
數(shù)組指針是指指向數(shù)組的指針。在Go語言中,你可以使用`&`操作符來獲取數(shù)組的地址,從而創(chuàng)建一個(gè)指向數(shù)組的指針。數(shù)組指針的類型是`*[長度]類型`。
var 變量名 *[數(shù)組大小] 數(shù)組類型:
var arrPtr *[size] Type
初始化指針可以通過 new 函數(shù)來分配內(nèi)存并返回指針的地址:
p := new(int) // 分配一個(gè) int 類型的內(nèi)存,并將指針 p 指向該內(nèi)存
因?yàn)閿?shù)組指針是一個(gè)指針,所以在定義時(shí),先寫 *, 表示定義一個(gè)指針,后面接數(shù)據(jù)類型
運(yùn)行結(jié)果:
注意,輸出的結(jié)果不是地址(不是 16 進(jìn)制的數(shù)),在 Golang 中,直接輸出的是&[元素 1 元素 2 ……]
我們可以輸出一下二者的地址:
fmt.Printf("arr 數(shù)組的地址為:%p\n", &arr) fmt.Printf("arrPtr 存儲(chǔ)的地址為:%p\n", arrPtr)
可以看到,它倆的輸出時(shí)一樣的,因?yàn)閷?shù)組 arr 的地址賦值給了 arrPtr,而 arrPtr 是一個(gè)指針,存儲(chǔ)的是內(nèi)存地址。
當(dāng)然 arrPtr 也有自己的內(nèi)存地址,我們可以看一下:
fmt.Printf("arrPtr 指針自己的地址為:%p\n", &arrPtr)
輸出為:
arrPtr 指針自己的地址為:0xc000006028
2.1獲取指針的地址和解使用
通過 & 操作符可以獲取變量的地址,例如:
x := 10 p := &x // 將指針 p 指向變量 x 的地址 ? a := 10 b := &a // 將指針 b 指向變量 a 的地址
使用 * 操作符可以解引用指針,獲取指針指向的值 :
fmt.Println(*p) // 輸出指針 p 指向的值,即變量 x 的值
輸出結(jié)果:
type of b:*int
type of c:int
value of c:10
取地址操作符 & 和取值操作符 * 是一對(duì)互補(bǔ)操作符,& 取出地址,* 根據(jù)地址取出地址指向的值。
3.通過指針訪問數(shù)組
訪問數(shù)組的元素可以通過下標(biāo)來訪問,比如:arr [0] 即可訪問數(shù)組 arr 的第一個(gè)元素。
但是我們學(xué)習(xí)了指針數(shù)組,所以嘗試使用指針數(shù)組來訪問元素內(nèi)容,在 Golang 中,取地址的操作為 * (尋址運(yùn)算符) 。
因此,我們先取存儲(chǔ)的地址 *arrPtr,訪問到數(shù)組 ,然后再下標(biāo)取值 *arrPt[0],代碼如下:
*arrPtr[0]
- 實(shí)際上,這段代碼編譯就會(huì)報(bào)錯(cuò),因?yàn)樵?Golang 中 * 尋址運(yùn)算符和 [] 中括號(hào)運(yùn)算符的優(yōu)先級(jí)是不同的!
- [] 中括號(hào)是初等運(yùn)算符
- 尋址運(yùn)算符是單目運(yùn)算符
- 初等運(yùn)算符的優(yōu)先級(jí)是大于單目運(yùn)算符的,因此先參與計(jì)算的是 arrPtr[0],arrPtr[0] 其實(shí)就是數(shù)組的第一個(gè)元素,就是數(shù)字 1。
- 數(shù)字 1 必然是 int 類型,而不是一個(gè)地址,因此針對(duì)數(shù)字 1 使用 * 尋址運(yùn)算符自然也就發(fā)生了錯(cuò)誤。
解決問題的辦法很簡單,就是添加一個(gè)小括號(hào),更改運(yùn)算優(yōu)先級(jí)即可:
(*arrPtr)[0]
- 不過因?yàn)?* 在 Golang 中,建立了 arrPtr := &arr 這種類似地址關(guān)系后,* 允許不寫。
- 所以,訪問時(shí)候可以直接寫成 arrPtr[0]。事實(shí)上在工作開發(fā)過程中,這種寫法反而更加常見。實(shí)戰(zhàn)代碼:
fmt.Println("(*arrPtr)[0] 通過指針訪問數(shù)組的第一個(gè)元素:", (*arrPtr)[0]) fmt.Println("arrPtr[0] 通過指針訪問數(shù)組的第一個(gè)元素:", arrPtr[0])
輸出:
(*arrPtr)[0] 通過指針訪問數(shù)組的第一個(gè)元素: 1
arrPtr[0] 通過指針訪問數(shù)組的第一個(gè)元素: 1
4.指針數(shù)組
在Go語言中,指針數(shù)組是指一個(gè)數(shù)組,其元素時(shí)指針,指針元素通常用于存儲(chǔ)多個(gè)指針,這些指針可以指向不同類型的數(shù)據(jù)結(jié)構(gòu),如結(jié)構(gòu)體,數(shù)組,基本數(shù)據(jù)類型等等。
它是一個(gè)數(shù)組,該數(shù)組的元素都為地址值
var 變量名 [數(shù)組大小] * 數(shù)組類型:
var ptrArr [size] *Type
因?yàn)橹羔様?shù)組是一個(gè)數(shù)組,所以在定義時(shí),先寫 [size], 表示定義一個(gè)數(shù)組,后面再接指針 * 和 數(shù)組的數(shù)據(jù)類型
實(shí)例:
1. 創(chuàng)建一個(gè)數(shù)組指針, 數(shù)組的類型為 int,大小為 4,并賦值:
package main import "fmt" func main() { var ptrArr [4]*int a,b,c,d := 1,2,3,4 arr2 :=[4]int{a,b,c,d}//拷貝四個(gè)變量的值為函數(shù)組元素 fmt.Println(arr2) ptrArr =[4]*int{&a,&b,&c,&d}//拷貝四個(gè)變量的地址值給函數(shù)組元素 fmt.Println(ptrArr) }
輸出:
數(shù)組 arr2 : [1 2 3 4]
指針數(shù)組 ptrArr : [0xc0000140f0 0xc0000140f8 0xc000014100 0xc000014108]
2. 操作數(shù)據(jù),查看變化
(1).arr2 的第一個(gè)元素改變,a 會(huì)不會(huì)變化,ptrArr 會(huì)不會(huì)變化?
arr2[0] = 100 fmt.Println("arr2 的值為:", arr2) fmt.Println("a 的值為;", a) fmt.Println("ptrArr 的值為;", *ptrArr[0])
輸出:
arr2 的值為: [100 2 3 4]
a 的值為; 1
ptrArr 的值為; 1
先看 a 的值為 1 解釋:
在 Golang 中,int,float,bool,string,array,struct 都屬于值類型,數(shù)據(jù)拷貝時(shí)都是值拷貝,拷貝副本過來。
因此,盡管 arr2[0] = 100 執(zhí)行了,只是修改了 arr2 的值,原來 a 的值不會(huì)受任何影響。因此,a 的值仍為 1
ptrArr 的值為 1 解釋:
ptrArr 是指針數(shù)組, 該數(shù)組存儲(chǔ)都是 指針,也就是 a,b,c,d 四個(gè)變量的內(nèi)存地址。
其中,*ptrArr[0] 存儲(chǔ)的是 a 的內(nèi)存地址;a 沒變, *ptrArr[0] 也不會(huì)變。所以輸出仍為 1
我們可以查看一下 ptrArr[0] 的值和 a 的地址是否一致:
fmt.Println("ptrArr[0] 的值:", ptrArr[0]) fmt.Printf("a 的內(nèi)存地址為:%p\n", &a) // %p 占位符表示地址值
輸出:
ptrArr[0] 的值: 0xc0000140f0
a 的內(nèi)存地址為:0xc0000140f0
(2). 指針數(shù)組變化,a,b,c,d 會(huì)不會(huì)改變? 數(shù)組 arr2 會(huì)不會(huì)改變?
*ptrArr[0] = 1000 // 指針數(shù)組的第一個(gè)元素地址指向的值發(fā)生改變 fmt.Println("a 的值為:", a) fmt.Println("arr2 的值為:", arr2)
輸出:
a 的值為: 1000
arr2 的值為: [100 2 3 4]
a 的值為: 1000 解析:
首先要明白一點(diǎn):*ptrArr[0] = 1000 這段代碼不會(huì)編譯報(bào)錯(cuò),因?yàn)?ptrArr 是指針數(shù)組,按照運(yùn)算符的執(zhí)行順序,先 ptrArr[0] 獲取 a 的地址,然后再 *a,這樣獲取的就是 a 的值
其實(shí),解析的已經(jīng)差不多了,ptrArr[0] 本來就是 a 的內(nèi)存地址,所以 *ptrArr[0] = 1000 執(zhí)行后,就改變了 a 的值
arr2 的值為: [100 2 3 4] 解析:
arr2 拷貝了 a,b,c,d 值的副本,a 的改變和 arr2 沒有關(guān)系的,各不會(huì)受影響。a 和 arr2 都是值類型,各自改變,互不影響
到此這篇關(guān)于go語言中的數(shù)組指針和指針數(shù)組的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)go 數(shù)組指針和指針數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言中未知異常捕獲的多種場(chǎng)景與實(shí)用技巧
在Go語言編程中,異常處理是確保程序健壯性的關(guān)鍵環(huán)節(jié),與一些其他編程語言不同,Go沒有傳統(tǒng)的try - catch結(jié)構(gòu)化異常處理機(jī)制,本文將深入探討Go語言中未知異常捕獲的多種場(chǎng)景與實(shí)用技巧,需要的朋友可以參考下2024-11-11Go語言通過chan進(jìn)行數(shù)據(jù)傳遞的方法詳解
這篇文章主要為大家詳細(xì)介紹了Go語言如何通過chan進(jìn)行數(shù)據(jù)傳遞的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-06-06Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法
這篇文章主要介紹了Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10Golang負(fù)載均衡和?;钤O(shè)計(jì)原理示例探究
這篇文章主要為大家介紹了Golang負(fù)載均衡和?;钤O(shè)計(jì)原理示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01golang項(xiàng)目如何上線部署到Linu服務(wù)器(方法詳解)
這篇文章主要介紹了golang項(xiàng)目如何上線部署到Linu服務(wù)器,本文通過兩種方法給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10gorm FirstOrCreate和受影響的行數(shù)實(shí)例
這篇文章主要介紹了gorm FirstOrCreate和受影響的行數(shù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12