數組形參會被弱化為指針,所以處理數組的函數通常通過指向數組中元素的指針來處理數組。
// three equivalent definitions of printValues void printValues(int *) { /* … */ } void printValues(int []) { /* … */ } void printValues(int [10]) { /* … */ }
上面3種定義等價,形參類型都是int *,通常使用第1種。第2種形式雖然看起來更直觀,但容易引起誤解,因為函數操縱的畢竟不是數組本身,而是指向數組元素的指針。第3種形式的數組長度是被忽略的,這里的10並無實際的約束作用,在printValues內部不應依賴這個數組長度做事情。
和其他類型一樣,形參也可以是數組的引用。這時編譯器不會將數組實參轉換為指針,而是傳遞數組的引用本身。數組大小成為形參和實參類型的一部分。編譯器檢查數組實參的大小與形參的大小是否匹配。
// ok: parameter is a reference to an array; size of array is fixed void printValues(int (&arr)[10]) { for (size_t i = 0; i != 10; ++i) cout << arr[i] << endl; } int main() { int i = 0, j[2] = {0, 1}; int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; printValues(&i); // error: argument is not an array of 10 ints printValues(j); // error: argument is not an array of 10 ints printValues(k); // ok: argument is an array of 10 ints return 0; }
這個版本的printValues只嚴格接受含有10個ints的數組,所以在printValues函數體內依賴數組大小也是安全的。&arr兩邊的括號是必須的,否則int &arr[10],會被當做是含有10個引用的數組。
也可以傳遞多維數組,所謂多維數組實際就是數組的數組。多維數組同樣以指向首元素的指針方式傳遞。除了第一維以外的所有維的長度都必須明確指定。
// first parameter is an array whose elements are arrays of 10 ints void printValues(int (*matrix)[10], int rowSize); void printValues(int matrix[][10], int rowSize);
實際上形參還是被弱化為一個指針,只不過它現在所指向的是含有10個ints的數組。
因為非引用型數組形參被弱化為指針,所以無法得知數組的大小,這就容易造成數組越界。一般處理方法有以下三種。
(1)在數組尾端放置一個結束標記,類似於c-style字符串的\0結束符。
(2)傳遞指向數組的第一個和最后一個元素的下一位置的指針,c++標准庫程序采用這種方法。
void printValues(const int *beg, const int *end) { while (beg != end) cout << *beg++ << endl; }
(3)顯示傳遞表示數組大小的形參
void printValues(const int ia[], size_t size) { for (size_t i = 0; i != size; ++i) cout << ia[i] << endl; }
【學習資料】 《c++ primer》