【C++ Lab】 對於解引用符*以及與運算符[]優先級的探索
我想很多人都看過運算符優先級表,但有時候對於一些情況可能會混淆,不過一個萬能方法是——加括號改變/確保優先級。儘管"加括號"確實是個萬能方法,但在有時間去摸索的時候還是儘可能弄清楚優先級爲好,這樣更有助於理解,甚至可以在摸索的過程中發現"新大陸",這也是做此次探索的目的。
【結論】
先把結論擺上吧:
【結論一】解引用符*不能"解空氣",即被解引用的指針變量不能爲野地址或NULL
【結論二】運算符[]的優先級高於解引用符*。因此對於一個二級指針如int** a;
,如果要用它來表示一個一維數組,則數組中元素表示爲(*a)[i]
,其中的小括號不能少。
【驗證過程】
階段一 探究初步
#include<iostream>
#include<stdlib.h>
int main(){
using namespace std;
int ** a=NULL; //注意懸空,防止野指針
//cout<<"a="<<a<<endl;
*a = (int*)malloc(sizeof(int)*3);
for(int i=0;i<3;++i)
(*a)[i] = i+1;
for(int i=0;i<3;++i)
cout<<(*a)[i]<<endl;
return 0;
}
【運行結果】
階段二 理解解引用符——*
以上爲我一開始寫的代碼,但是一運行就發現main函數返回了一個很大的值(如上圖),顯然是出現了問題(即便我不把指針變量a懸空也是如此),其實原因很簡單,我當時並沒有給指針變量a本身提供一個"合法處所",即少了一句a=(int**)malloc(sizeof(int));
,但這就使得二級指針a充當着二維數組了(我們是想要把二級指針a用於一維數組),因此我把代碼改了改,如下代碼塊所示。
#include<iostream>
#include<stdlib.h>
int main(){
using namespace std;
int ** a=NULL; //注意懸空,防止野指針
int* arr=NULL;
a = &arr;
//cout<<"a="<<a<<endl;
*a = (int*)malloc(sizeof(int)*3);
for(int i=0;i<3;++i)
(*a)[i] = i+1;
for(int i=0;i<3;++i)
cout<<(*a)[i]<<endl;
return 0;
}
【運行結果】
可能有人會有疑問了,爲何在不改變第一個代碼塊代碼的前提下,僅僅添加了int* arr=NULL; a=&arr;
後,就能正常運行了呢?關鍵在於a指針變量所指的地址是否存在。
我們要明白*a的意思是"對於a所指的地址解引用,並取其存儲的值",對於一開始的int ** a=NULL; *a = (int*)malloc(sizeof(int)*3);
,a是空指針,沒有指向實際的地址,這時候*a即取虛空地址存儲的值,相當於"取空氣",這當然是非法的了,這種情況下就需要先給a本身申請一個存儲空間,也就是對應着a=(int**)malloc(sizeof(int));
,然後再進行後續的解引用等指令。
對於後面的代碼塊,這時候a=&arr;
,儘管arr=NULL
,但是它的地址是非空的,即&arr!=NULL
,這時候賦予a的自然就是一個實實在在的"合法處所"了,因此*a——對於a的解引用就是"名正言順"了。
到此我們可以得出【結論一】:解引用符*不能"解空氣",即被解引用的指針變量不能爲野地址或NULL
階段三 步入正題——[]與*優先級探索
這一步其實很簡單,我們只要把第二個代碼塊中(*a)[i]
所加的小括號去掉就好,如果運行結果符合預期,那麼就說明解引用符*的優先級高於運算符[];若運行出錯,則說明解引用符* 的優先級低於運算符[]。
#include<iostream>
#include<stdlib.h>
int main(){
using namespace std;
int ** a=NULL; //注意懸空,防止野指針
int* arr=NULL;
a = &arr;
cout<<"The address of arr is "<<&arr<<endl;
*a = (int*)malloc(sizeof(int)*3);
for(int i=0;i<3;++i)
*a[i] = i+1;
for(int i=0;i<3;++i)
cout<<*a[i]<<endl;
return 0;
}
【運行結果】
去掉小括號運行就出錯了,從而得到了我們的【結論二】:運算符[]的優先級高於解引用符*
所以有些時候,如果對於網上的答案持懷疑態度,那麼不妨自己設計個簡單實驗試試,說不定你就找到了答案,並且這遠比你去網上搜尋得到的解答印象深刻。
如果文章中有不妥之處,歡迎大家在評論區指點批評~