C++複合數據類型之數組和指針

上一篇講了C++的基本數據類型,這一篇就來講一講C++的複合類型:數組,指針和結構。

int a[10];

int* p;

 

注意:

1.a的類型不是數組,而是int數組,這強調了a數組是使用int類型創建的。

2.數組在內存中是按行優先存放的,即a[0],a[1]的地址是連續的,這在將來使用多維數組時需要注意

3.指針時一種特殊的類型,只有地址能夠賦值給他。

 

創建了一個數組,就是在內存中分配一塊連續的內存用於存放特定類型的數據,既然有內存,那麼就會涉及到內存地址,這裏的數組名a就是數組的地址,但需要注意的是數組有那麼多個值,a是哪個值的地址呢?實際上a是數組第一個項的地址,即&a[0],但同時a也是整個數組的地址,即存放整個數組的內存塊的地址可以通過&a獲取這個地址。

前面說了,數組的內存是連續的,而這裏又知道了數組第一個項的地址,那麼就可以通過這個地址進行做加法獲取數組其他項的地址了。涉及到地址的時候指針就可以派上用場了。數組名中存放的又是地址,也就是說其實數組名就是一個指針了。那就可以通過對數組首地址做加法獲取其他地址,那就需要先了解一下指針算數了。

p+1加的並不是1,而是p的類型的字節數,這裏p加的是4.

eg:假設p中存放的地址是1000,那麼p+1就等於1004,

如果p的類型是double,且double長度爲8個字節,那麼p+1就是1008.

 

再回到之前的獲取數組項地址,在使用a,而不是&a的時候a是數組第一項的地址,也就是說a的類型是數組項的類型,所以a+1就是地址加了4,正好是數組第二項的地址,即數組下標爲n的地址可以通過a+n獲取。那麼&a+1是什麼意思呢,既然&a是整個數組塊的地址,也就是說&a的類型是這個數組類型,類型長度即數組長度了,即&a+1相當於加了數組的長度,這裏是40,指向的是數組最後一項向後移動4個字節的位置。

所以數組項可以通過a[n]獲取,也可以通過*(a+n)獲取,若p=a,甚至可以通過p[n],*(p+n)獲取

 

到這裏,就已經明白了數組名就相當於一個指針了,那麼接下來就討論在函數間傳遞數組作爲參數了。

之前沒有使用數組傳參的人可能會以爲這個可以:

函數原型:void fun(inta[]);

函數調用: fun(a[10]);

這不是把整個參數傳遞了嗎?實際上a[10]本身就是錯的,數組越界了,即便沒有越界,a[10]代表的也是數組的第10項而不是整個數組。那麼如何傳遞數組呢?前面說過數組可以通過數組名來獲取數組所有項的地址,有了地址自然就可以獲取值了,所以,數組傳參傳遞的實際是數組地址,也就是數組名了。

正確的調用方式是:

func(a);

因爲傳遞的只是地址,所以函數內其實並不知道數組的長度,所以一般將數組的長度一起傳入:

void fun(int a[],int length)

fun(a,10);

注意:1.C++並不會檢查數組索引是否越界,即在函數中的a[10]也是合法的,但是其中的值是未知的。

既然傳的是地址,那麼函數的聲明就可以改爲如下:

void fun(int* a,int length);

這樣也是正確的,在函數內部使用該數組的方式也是一樣的。

 

注意: 1.在函數內部sizeof(a)=4,在數組聲明處sizeof(a)=40,因爲函數內部的a只是一個地址編譯器並不會爲他分配數組塊大小的內存,而只是爲他分配存放int型指針的內存,在數組聲明處則不同,編譯器會分配數組塊大小的內存,並將這個地址保存到a(實際上就是分配的內存處)。

 


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