C 指標陣列與陣列指標詳解

2021-08-17 00:02:53 字數 2892 閱讀 2410

首先先定義乙個指標陣列,既然是陣列,名字就叫arr

char *arr[4] = ;
//arr就是我定義的乙個指標陣列,它有四個元素,每個元素是乙個char *型別的指標,這些指標存放著其對應字串的首位址。
// 即 char*(arr[4]

)

(當乙個變數出現左右都出現乙個運算子時,沒有記住運算子優先順序的人就會糾結arr變數到底跟哪乙個運算子先結合。如果是自己定義乙個指標陣列,搞不清楚運算子的優先順序,那麼就加上小括號(),比如定義乙個指標陣列,可以寫成char *(arr[4]),不過在定義之前一定要清楚自己定義的變數,如果目的是乙個陣列,那就把arr[4]括起來,如果是乙個指標,就把*arr括起來。如果是看到一段這樣的**,可以從他的初始化來分別它是陣列還是指標,很明顯,我這定義的是乙個陣列,如果是指標,會用null來初始化。)

這個指標陣列有多大呢?答案是16個位元組,因為它是乙個指標陣列。(這是廢話,正話下面說) 

每當出現這些問題時,腦子裡一定要第一時間反應出記憶體映像圖

記憶體映像象圖

內容許可權

棧區函式中的普通變數

可讀可寫

堆區動態申請的記憶體

可讀可寫

靜態變數區

static修飾的變數

可讀可寫

資料區用於初始化變數的常量

唯讀**區

**指令

唯讀這裡最左側一列是乙個很簡陋但能說明意思的記憶體圖,一般情況下,從棧區到**區,是從高位址到低位址。棧向下增長,堆向上增長。

arr[4]是乙個在主函式定義的陣列。把它對應到對應到記憶體中,arr是乙個在棧區,有四個元素的陣列,而每乙個陣列又是乙個指標,所以說它的四個元素各佔四個位元組,所以變數arr的大小是16個位元組。

那麼就有人問了?初始化arr的;的是什麼鬼? 

這四個不是什麼鬼,他們也存在在記憶體中,只是跟arr這個變數不在同一段空間,它們被分配在唯讀資料區,陣列arr[4]的四個指標元素,分別存放著這四個字串的首位址,想象一下,從棧區有四隻無形的手指向資料區的空間。arr+1會跳過四個位元組,。也就是乙個指標的大小 

這就相當與定義char *p1 = 「hello」,char *p1 = 「world」,char *p3 = 「shannxi」, char *p4 = 「xian」,這是四個指標,每個指標存放乙個字串首位址,然後用arr[4]這個陣列分別存放這四個指標,就形成了指標陣列。

首先來定義乙個陣列指標,既然是指標,名字就叫pa

char(*pa)[4]

如果指標陣列和陣列指標這倆個變數名稱一樣就會是這樣:char *pa[4]和char (*pa)[4],原來指標陣列和陣列指標的形成的根本原因就是運算子的優先順序問題,所以定義變數是一定要注意這個問題,否則定義變數會有根本性差別!

pa是乙個指標指向乙個char [4]的陣列,每個陣列元素是乙個char型別的變數,所以我們不妨可以寫成:char[4] (*pa);這樣就可以直觀的看出pa的指向的型別,不過在編輯器中不要這麼寫,因為編譯器根本不認識,這樣寫只是幫助我們理解。

既然pa是乙個指標,存放乙個陣列的位址,那麼在我們定義乙個陣列時,陣列名稱就是這個陣列的首位址,那麼這二者有什麼區別和聯絡呢?

char a[4];

a是乙個長度為4的字元陣列,a是這個陣列的首元素首位址。既然a是位址,pa是指向陣列的指標,那麼能將a賦值給pa嗎?答案是不行的!因為a是陣列首元素首位址,pa存放的卻是陣列首位址,a是char 型別,a+1,a的值會實實在在的加1,而pa是char[4]型別的,pa+1,pa則會加4,雖然陣列的首位址和首元素首位址的值相同,但是兩者操作不同,所以型別不匹配不能直接賦值,但是可以這樣:pa = &a,pa相當與二維陣列的行指標,現在它指向a[4]的位址。

指標陣列常用在主函式傳參,在寫主函式時,引數有兩個,乙個確定引數個數,乙個這是指標陣列用來接收每個引數(字串)的位址

int main(int argc, char *argv)

此時可以想象記憶體映像圖,主函式的棧區有乙個叫argv的陣列,這個陣列的元素是你輸入的引數的位址,指向著唯讀資料區。

如果是向子函式傳參,這和傳遞乙個普通陣列的思想一樣,不能傳遞整個陣列過去,如果陣列很大,這樣記憶體利用率很低,所以應該傳遞陣列的首位址,用乙個指標接收這個位址。因此,指標陣列對應著二級指標

void fun(char **pp);//子函式中的形參

fun(char *p);//主函式中的實參

3.2指標陣列的排序

指標陣列的排序非常有趣,因為這個陣列中存放的是指標,通過比較指標指向的空間的大小,排序這些空間的位址。函式實現如下:

void sort(char **pa, int n)//氣泡排序}}

}

在函式中定義指標陣列,並且列印結果如下:

char *pa[4] = ;

[root@menwen-linux test]# ./test

abcijk

opqxyz

陣列指標既然是乙個指標,那麼就是用來接收位址,在傳參時就接收陣列的位址,所以陣列指標對應的是二維陣列。

void fun(int (*p)[4]);//子函式中的形參,指標陣列 

a[3][4] = ;//主函式中定義的二維陣列

fun(a);//主函式呼叫子函式的實參,是二維陣列的首元素首位址

指標陣列與陣列指標詳解

首先先定義乙個指標陣列,既然是陣列,名字就叫arr char arr 4 arr就是我定義的乙個指標陣列,它有四個元素,每個元素是乙個char 型別的指標,這些指標存放著其對應字串的首位址。當乙個變數出現左右都出現乙個運算子時,沒有記住運算子優先順序的人就會糾結arr變數到底跟哪乙個運算子先結合。如...

指標陣列與陣列指標詳解

指標的陣列 首先這個變數是乙個陣列,其次,指標 修飾這個陣列,意思是說 這個陣列的所有元素都是指標型別 在32位系統中,指標佔四個位元組 陣列指標 陣列指標可以說成是 陣列的指標 首先這個變數是乙個指標,其次,陣列 修飾這個指標,意思是說這個指標存放著乙個陣列的首位址,或者說這個指標指向乙個陣列的首...

指標陣列與陣列指標 詳解

指標陣列和 陣列指標的區別 指標陣列 傳遞多個字串用 int p 10 陣列先運算,指標 修飾陣列 陣列指標 傳遞乙個陣列的首位址用 int p 10 指標先運算,陣列修飾指標,二維陣列和 指標陣列的區別 二維陣列int p 10 20 行列固定 指標陣列int p 10 10個陣列,每個陣列都指向...