【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;
}

【運行結果】
在這裏插入圖片描述
去掉小括號運行就出錯了,從而得到了我們的【結論二】:運算符[]的優先級高於解引用符*

所以有些時候,如果對於網上的答案持懷疑態度,那麼不妨自己設計個簡單實驗試試,說不定你就找到了答案,並且這遠比你去網上搜尋得到的解答印象深刻。

如果文章中有不妥之處,歡迎大家在評論區指點批評~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章