Let*_*_Be 56
起源是历史的.问题是规则"数组在传递给函数时衰减为指针"很简单.
复制数组会有点复杂而且不太清楚,因为不同参数和不同函数声明的行为会发生变化.
请注意,您仍然可以按值进行间接传递:
struct A { int arr[2]; };
void func(struct A);
Run Code Online (Sandbox Code Playgroud)
Ker*_* SB 28
这是另一个视角:C中没有一个类型的"数组".相反,每个类型T[N]
都是不同的类型N
.所以T[1]
,T[2]
等等,都是不同的类型.
在C中没有函数重载,所以你可以允许的唯一合理的东西是一个接受(或返回)单一类型数组的函数:
void foo(int a[3]); // hypothetical
Run Code Online (Sandbox Code Playgroud)
据推测,这被认为远没有实际决定使所有数组衰变为指向第一个元素的指针并且要求用户通过其他方式传递大小的实用决策.毕竟,以上内容可以改写为:
void foo(int * a)
{
static const unsigned int N = 3;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
因此,没有表现力的损失,但一般性的巨大收益.
请注意,这在C++中没有任何不同,但模板驱动的代码生成允许您编写模板化函数foo(T (&a)[N])
,在N
此为您推导出 - 但这只是意味着您可以创建一系列不同的,不同的函数,一个对于每个值N
.
作为一个极端的例子,想象一下你需要两个函数print6(const char[6])
并print12(const char[12])
说print6("Hello")
,print12("Hello World")
如果你不想将数组衰减到指针,或者你必须添加一个显式转换,print_p((const char*)"Hello World")
.
小智 9
回答一个很老的问题,因为Question是C ++的市场,只是出于完成目的而添加,我们可以使用std :: array并将数组按值或引用传递给函数,从而防止访问超出范围的索引:
下面是示例:
#include <iostream>
#include <array>
//pass array by reference
template<size_t N>
void fill_array(std::array<int, N>& arr){
for(int idx = 0; idx < arr.size(); ++idx)
arr[idx] = idx*idx;
}
//pass array by value
template<size_t N>
void print_array(std::array<int, N> arr){
for(int idx = 0; idx < arr.size(); ++idx)
std::cout << arr[idx] << std::endl;
}
int main()
{
std::array<int, 5> arr;
fill_array(arr);
print_array(arr);
//use different size
std::array<int, 10> arr2;
fill_array(arr2);
print_array(arr2);
}
Run Code Online (Sandbox Code Playgroud)
您无法按值传递数组的原因是,因为没有特定的方法来跟踪数组的大小,因此函数调用逻辑将知道要分配多少内存以及要复制的内容。您可以传递类实例,因为类具有构造函数。数组没有。