1.1 乙個指標包含兩方面:a) 位址值;b) 所指向的資料型別。
1.2 解引用操作符(dereference operator)會根據指標當前的位址值,以及所指向的資料型別,訪問一塊連續的記憶體空間(大小由指標所指向的資料型別決定),將這塊空間的內容轉換成相應的資料型別,並返回左值。
有時候,兩個指標的值相同,但資料型別不同,解引用取到的值也是不同的,例如,
[cpp]view plain
copy
char
str =;
/* 以字元的ascii碼初始化 */
char
* pc = &str[0];
/* pc指向str[0],即0 */
int* pi = (
int*) pc;
/* 指標的「值」是個位址,32位。 */
此時,pc和pi同時指向str[0],但*pc的值為0(即,ascii碼值為0的字元);而*pi的值為50462976。或許把它寫成十六進製制會更容易理解:0x03020100(4個位元組分別為3,2,1,0)。我想你已經明白了,指標pi指向的型別為int,因此在解引用時,需要訪問4個位元組的連續空間,並將其轉換為int返回。
2.1 陣列名和指標
通常我們認為陣列名是乙個指標常量(例如,int a[10]; 那麼a是乙個int * const),這種理解是不全面的,正確的理解如下:
作為右值(例如,賦值語句右邊)時陣列名可視為指標常量(系統自動轉換);作為左值,例如取位址,sizeof,則不能視為指標。
sizeof(乙個陣列)返回的是陣列大小*每個元素佔位元組數;而sizeof(乙個指標)返回4。
2.2 二維陣列
實際上,不管是一維還是多維陣列,都是記憶體中一塊線性連續空間,因此在記憶體級別上,其實都只是一維。
(在參考資料2基礎上稍作更改)
做如下定義:
[cpp]view plain
copy
inta[3][4] = ;
int** p;
p = (int
**)a;
/* 不做強制型別轉換會報錯 */
說明:1)p是乙個二級指標,它首先是乙個指標,指向乙個int*;
2)a是二維陣列名,它首先是乙個指標,指向乙個含有4個元素的int陣列;
由此可見,a和p的型別並不相同,如果想將a賦值給p,需要強制型別轉換。
假如我們將a賦值給p,p = (int**)a; 既然p是二級指標,那麼當然可以這麼用:**p; 這樣會出什麼問題呢?
1)首先看一下p的值,p指向a[0][0],即p的值為a[0][0]的位址;
2)再看一下*p的值,p所指向的型別是int*,佔4位元組,根據前面所講的解引用操作符的過程:從p指向的位址開始,取連續4個位元組的內容。得到的正式a[0][0]的值,即0。
3)再看一下**p的值,誒,報錯了?當然報錯了,因為你訪問了位址為0的空間,而這個空間你是沒有許可權訪問的。
實際上這是某一年華為的面試題。感興趣的還可以把a的型別定義為char型別的二維陣列,看看會發生什麼。
(**參考資料3)
二維陣列名 二維陣列名取位址 二級指標
先給出結論,便於以後查閱 首先給出幾個定義 typedef int p1x4 4 定義資料型別,p1x4這種型別為指向含4個int元素的1維陣列的指標 typedef int p3x4 3 4 定義資料型別,p3x4這種型別為指向含3x4個int元素的2維陣列的指標 下面從一維陣列說起 定義 int...
二維陣列和二維陣列名
對於一位陣列我們認識到其資料元素在記憶體中是按線性順序依次排列的,且一維陣列名的值是乙個指標常量。那麼二維陣列在記憶體中又是怎麼儲存的,其陣列名又有什麼含義呢?定義乙個二維陣列 int arr 3 4 我們可以將乙個二維陣列看做是乙個其中元素為陣列的乙個一位陣列,也就是說二維陣列第一維的元素實際上是...
二維陣列和二級指標
前兩天寫個程式,傳引數的時候想傳個二維陣列進去,結果悲劇了,函式寫成fun int p 原來沒有這麼寫過,以為這麼寫也是對的,結果錯了,查了些資料,做個總結。fun int p 這裡面的int p 這裡的p不是二維陣列的指標,而是指向指標的指標,即二級指標。正確的二維陣列的指標應該是 int a 2...