關於利用陣列名獲取陣列大小的一點誤區 - [C&CPP]

鴨脖發表於2012-12-15
  • 眾所周知,在C++中,當我們使用一個陣列引數作為一個函式的引數的時候,該陣列名將會退化為一個指標。
  • 另,我們知道在C++中可以使用sizeof(a)獲取陣列a的大小(多少個位元組);
  • 但常常我們在對一個從形參傳進來的陣列怎麼獲取長度了,還可以使用sizeof(a)嗎?答案是否定的。                 因為經過了實參到形參的轉換,該陣列名已經退化為一個名副其實的指標了(作業系統將會重新生成一個新的區域性變數,該變數是一個指標,該指標指向了原陣列所在的記憶體)。此時我們已經無法通過該指標獲取到陣列的大小了。因此如果當我們在程式中將會使用到該陣列的大小(當我要遍歷該陣列的時候,需要判斷越界),我們應當使用形參來傳遞陣列的大小,而不是利用sizeof(a)來獲取陣列的大小;

 


下面我們來用程式來說明以上很饒舌的一段說明文字:


#include <iostream>
using namespace std;
int getSize(int data[]);
int main()
{
int data[] = {1,2,3,4,5,6,7};
cout<<"the address of data: "<<&data<<endl;
cout<<"the address of data[0]: "<<&data[0]<<endl;
cout<<"size: "<<getSize(data)<<endl;
return 1;

}
int getSize(int data[])
{
  cout<<"the address of data pointer: "<<&data<<endl;
  return sizeof(data)/sizeof(data[0]);
}


該程式執行結果如圖下所示:

the address of data: 0xbff918e4

the address of data[0]: 0xbff918e4

the address of data pointer: 0xbff918d0

size: 1

從上面的結果中我們可以得知,作業系統確實給我們重新分配了一個新的變數(指標data),我們通過sizeof(data)獲取到的是指標data的大小,所以最終獲得尺寸是1也是可以理解。
由此可見該程式並未達到我們想要的結果。亦即,如果我們想要在一個函式中獲取到一個陣列(該陣列是通過函式引數獲取的)的大小,惟有通過函式實參傳遞給形參。
例如:
int func(int data[],int n);

相關文章