C++引用形參+模板---解決陣列指標退化為指標
阿新 • • 發佈:2019-02-06
C/C++中如果一個函式接受一個數組作為引數,那麼陣列將會被退化為指標,如果定義如下程式碼:
//陣列arr的大小未知。
int arrsize(int arr*) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1
}
在上面那段程式碼中不僅得到的陣列大小是不正確的,還會出現讓呼叫則不明白是傳遞int變數的地址,還是傳遞一個指標(陣列),為了解決第二個歧義現象,我們可以定義如下:
//陣列arr的大小依舊未知。
int arrsize(int arr[]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1
}
即使我們按上面那種定義,但陣列的的大小我們依舊不知道,但現在編譯器還會提示類似如下警告:
warning: ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int*’ [-Wsizeof-array-argument]
為了更好的解決上面的問題我們可以考慮使用一個引用形參,可以有如下程式碼:
//陣列arr的大小必須是12,否則會報錯。
int arrsize_const_size(int (&arr)[12]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
}
即使我們使用引用形參解決了,在函式內部我們無法正確獲取陣列大小的問題,但更復雜的問題出現了,我們只能接受固定數量的大小的陣列,解決這個問題,我們可以通過一種很常規的手法定義函式如下:
//指定一個數組大小n
int arrsize_n(int arr[], int n) {
}
上面雖然解決了,但我們多傳遞了一個引數,呼叫程式碼看起來沒有前兩個更加簡潔了,雖然問題被很好的解決了,為了更好的解決這個問題我們可以把推斷陣列大小的事交個編譯器,使用非型別模板引數。
template<int n>
int arrsize_template_size(int (&arr)[n]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
cout << "n : " << n << endl;//12
for (int i = 0; i < n; i++) {
cout << "arr[" << i << "] = " << arr[i] << endl;
}
return 0;
}
下面給出完整的測試程式碼:
#include <iostream>
using namespace std;
//陣列arr的大小未知。
int arrsize(int arr[]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//1
return 0;
}
//陣列arr的大小必須是12,否則會報錯。
int arrsize_const_size(int (&arr)[12]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
return 0;
}
//指定一個數組大小n
int arrsize_n(int arr[], int n) {
return 0;
}
template<int n>
int arrsize_template_size(int (&arr)[n]) {
cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
cout << "n : " << n << endl;//12
for (int i = 0; i < n; i++) {
cout << "arr[" << i << "] = " << arr[i] << endl;
}
return 0;
}
int main() {
int arr[12] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
};
int arr1[16] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16,
};
arrsize(arr);
arrsize_const_size(arr);
cout << "-------------------------------------" << endl;
arrsize_template_size(arr);
cout << "-------------------------------------" << endl;
arrsize_template_size(arr1);
cout << "-------------------------------------" << endl;
return 0;
}