指针数组、数组指针、数组的区别与联系
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?指針數組、數組指針、數組的區別與聯系!
一:基本定義
1.指針數組
char *arr[4] = {"hello", "world", "shannxi", "xian"};
//arr就是我定義的一個指針數組,它有四個元素,每個元素是一個char *類型的指針,這些指針存放著其對應字符串的首地址。
(1)這個指針數組有多大呢?答案是16個字節,因為它是一個指針數組。(這是廢話,正話下面說) 每當出現這些問題時,腦子里一定要第一時間反應出內存映像圖如下:
這里最左側一列是一個很簡陋但能說明意思的內存圖,一般情況下,從棧區到代碼區,是從高地址到低地址。棧向下增長,堆向上增長。
(2)arr[4]是一個在主函數定義的數組。把它對應到對應到內存中,arr是一個在棧區,有四個元素的數組,而每一個數組又是一個指針,所以說它的四個元素各占四個字節,所以變量arr的大小是16個字節。
那么就有人問了?初始化arr的{“hello”, “world”, “shannxi”, “xian”};的是什么鬼??
這四個不是什么鬼,他們也存在在內存中,只是跟arr這個變量不在同一段空間,它們被分配在只讀數據區,數組arr[4]的四個指針元素,分別存放著這四個字符串的首地址,想象一下,從棧區有四只無形的手指向數據區的空間。arr+1會跳過四個字節,。也就是一個指針的大小 ,這就相當與定義char *p1 = “hello”,char *p1 = “world”,char *p3 = “shannxi”, char *p4 = “xian”,這是四個指針,每個指針存放一個字符串首地址,然后用arr[4]這個數組分別存放這四個指針,就形成了指針數組。
2.數組指針
首先來定義一個數組指針,既然是指針,名字就叫pa。
char (*pa)[4];
(1)char *pa[4]和char (*pa)[4],原來指針數組和數組指針的形成的根本原因就是運算符的優先級問題.
(2)pa是一個指針指向一個char [4]的數組,每個數組元素是一個char類型的變量,所以我們不妨可以寫成:char[4] (*pa);這樣就可以直觀的看出pa的指向的類型,不過在編輯器中不要這么寫,因為編譯器根本不認識,這樣寫只是幫助我們理解。
(3)既然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]的地址。
二:指針數組和數組指針的使用
1.指針數組的應用
(1)指針數組在參數傳遞時的使用
指針數組常用在主函數傳參,在寫主函數時,參數有兩個,一個確定參數個數,一個這是指針數組用來接收每個參數(字符串)的地址.
int main(int argc, char *argv[])
此時可以想象內存映像圖,主函數的棧區有一個叫argv的數組,這個數組的元素是你輸入的參數的地址,指向著只讀數據區。
如果是向子函數傳參,這和傳遞一個普通數組的思想一樣,不能傳遞整個數組過去,如果數組很大,這樣內存利用率很低,所以應該傳遞數組的首地址,用一個指針接收這個地址。因此,指針數組對應著二級指針。
void fun(char **pp);//子函數中的形參
fun(char *p[]);//主函數中的實參(2)指針數組的排序
指針數組的排序非常有趣,因為這個數組中存放的是指針,通過比較指針指向的空間的大小,排序這些空間的地址。函數實現如下:
在函數中定義指針數組,并且打印結果如下:
char *pa[4] = {"abc", "xyz", "opq", "xyz"};
[root@menwen-linux test]# ./test?
abc
ijk
opq
xyz
2.數組指針傳參時的使用
數組指針既然是一個指針,那么就是用來接收地址,在傳參時就接收數組的地址,所以數組指針對應的是二維數組。
void fun(int (*P)[4]);//子函數中的形參,指針數組?
a[3][4] = {0};//主函數中定義的二維數組
fun(a);//主函數調用子函數的實參,是二維數組的首元素首地址
?
總結
以上是生活随笔為你收集整理的指针数组、数组指针、数组的区别与联系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进程、线程、堆、栈的理解和区别!
- 下一篇: 静态链接库与动态链接库的优缺点