1.數組指針
(1)數組指針與指針數組
這倆概念原本在c語言中就是一個繞口令般的存在,儘管從類型角度來看兩者並沒什麼相似的地方。
但是在go語言中對這兩個類型的設定做出了一些不同的規定。首先交代一下基本概念:
數組指針:指的是一個指針,只不過這個指針指向了一個數組
eg:
var arr [5]int = [5]int{1,2,3,4,5};
var p *[5]int = &arr;
fmt.Println(p);//0xc00006a030
//此時p稱爲是數組arr的指針
//此時如果通過p訪問數組元素是 (*p)[2],結果是3
指針數組:指的是一個數組,這個數組裏面裝滿了指針。
eg:
var arr1 [5]int = [5]int{1,2,3,4,5};
var arr2 [5]int = [5]int{6,7,8,9,0};
var p1 *[5]int = &arr1;
var p2 *[5]int = &arr2;
var pArr [2]*[5]int = [2]*[5]int{p1,p2};
fmt.Println(pArr);//[0xc00006a030, 0xc00006a060]
//此時pArr稱爲是指針數組
//此時如果通過pArr訪問數組元素是 (*pArr[0])[2],結果是3
(2)地址相同、類型不同問題
在go語言中,內存地址相同並不意味着其表示的數據或者數據類型就完全相同。
eg:
var arr [5]int = [5]int{1,2,3,4,5};
p1,p2 := &arr,&arr[0];
fmt.Println(p1); //&[1,2,3,4,5] 整個數組的內存地址
fmt.Println(p2); //0xc0000180c0 數組第一個元素的內存地址
fmt.Printf("%T",p1); //*[5]int 數組指針
fmt.Printf("%T",p2); //*int 指針
(3)*號可以不寫問題
在go語言中通過指針去訪問指針所對應的地址處的值時,*允許不寫。
而這個規定又會催生一個由於go運算符優先級問題而催生的指針訪問問題。
eg:
var arr [5]int = [5]int{1,2,3,4,5};
p := &arr;
fmt.Println(*p[0]);
乍一看這段代碼並無任何問題。
因爲p是數組指針,*p就是數組本身,而*p[0]自然就是數組的第一個元素
但是事與願違,代碼的運行結果是一個錯誤!
這是因爲在go語言中*尋址運算符和[]中括號運算符的優先級是不同的!
[]中括號是初等運算符
*尋址運算符是單目運算符
初等運算符的優先級是大於單目運算符的,因此先參與計算的是p[0];
p[0]其實就是數組的第一個元素,就是數字1
數字1必然是int類型,而不是一個地址,因此針對數字1使用*尋址運算符自然也就發生了錯誤。
解決問題的辦法很簡單,就是添加一個小括號就可以了。
即:
(*p)[0]
不過因爲*在go語言中,建立了 p:=&arr 這種類似地址關係後,*允許不寫。
所以,訪問時候可以直接攜程p[0]。事實上在工作開發過程中,這種寫法反而更加常見。
ps:
僅對訪問下標時,*尋址運算符允許不寫!
go語言-數組指針
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.