[英]C++ : 2D array by reference? Why does this function work
參數printArray(int(&a)[n] [m])是什么意思? 為什么需要括號,為什么只需要向printArray函數提供1值? 函數在調用時如何知道n和m?
template <size_t n, size_t m>
void printArray(int (&a)[n][m]) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
int main(int argc, char* argv[])
{
cout << "Example I:" << endl;
int ab[2][5];
printArray(ab);
cout << "Example II:" << endl;
int b[2][5] = {{1, 2, 3}};
printArray(b);
cout << "Example III:"<< endl;
int c[][5] = {1, 2, 3, 4, 5, 6, 7};
printArray(c);
cout << "Example IV:" << endl;
int d[][5] = {{1, 2, 3, 4}, {5, 6}, {7}};
printArray(d);
}
參數
printArray(int (&a)[n][m])
是什么意思?
這意味着a
是對int[n][m]
類型的對象的引用。 int[n][m]
是m
個類型為int[n]
對象的數組。 int[n]
是int
類型的n
對象的數組。 因此, a
是對尺寸為n
和m
的二維數組的引用。
n
和m
是在template <size_t n, size_t m>
中聲明的模板參數。 兩個參數的類型均為size_t
,它是整數類型。
為什么需要括號
因為&令牌綁定到左側。 int&
是對int的引用。 int& a[n]
語法含義是a
是引用數組(但是不允許這種數組)。 括號用於消除&令牌是聲明對int的引用(數組)還是對數組的引用。
為什么只需要向printArray函數提供1個值?
該函數只有一個參數: a
。 如果傳遞的值可以綁定到適當類型的數組引用,則它可以工作。 在所有示例中,參數都是2d整數數組,因此它們是正確的。
函數在調用時如何知道n和m?
編譯器知道,因為數組的大小是數組類型的一部分。 並且由於模板參數的推導。 如果未明確指定模板參數,則可以從函數的參數中推導出模板參數。 在這種情況下,如果傳遞類型為int[2][5]
,則將n
推導為2,將m
推導為5。
您甚至可以添加模板類型參數,然后推導該參數:
template <size_t n, size_t m, typename T>
void printArray(T (&a)[n][m])
如果要傳遞2d整數數組,則T
將被推導為int
。
如果不允許引用數組,為什么編譯器不能推斷出括號是沒有必要的。
如果int &a[n]
表示對數組的引用,因為沒有引用數組,那么這會使程序員混淆int *a[n]
不是指向數組的指針,因為可以存在數組指針。
此外,這將增加不必要的特殊引用,從而使語言復雜化。
為什么不是這樣的形式:printArray(int [n] [m]&a)
更簡單地說,為什么不能用int[n] a
而不是int a[n]
聲明數組。 因為后者的語法是由C語言的設計師(大概是丹尼斯·里奇,當時是他)選擇的。
它只是通過引用獲取數組。 至於在函數內部使用傳遞的數組,通常您將編寫與其他代碼完全相同的代碼。 唯一的區別是它保留其數組類型。
當您將數組“按值”傳遞給函數時,它實際上會衰減為指向其第一個元素的指針。 通過引用(或通過地址)傳遞它可以防止這種用法的這種衰減。
實際上,即使您為參數中的第一個維度指定范圍,但如果將數組“按值”傳遞,編譯器也將忽略它。
這是一個模板編程技巧,可以推斷出第一維的范圍,如果您編寫以下內容,則可能會丟失:
template<size_t m>
void printArray(int a[][m]) {...}
因此,替代方案可能會不太整潔,例如:
template<size_t m>
void printArray(int a[][m], size_t n) {...}
括號是必需的,因為int &a[n][m]
是2D引用數組,這是非法的,因為您不能創建引用數組。 int (&a)[n][m]
的括號表示此“對int的nxm數組的引用”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.