C和C++允许将结构体和对象的值传递给函数,但不允许将数组的值传递给函数。
为什么?
在CC++中,数组在内部是作为指向某个位置的指针来传递的,基本上,它是 是 值传递的。问题是,那个复制的值代表了一个内存地址,到了 同地.
在C++中,一个 vector<T>
是复制并传递给另一个函数的,顺便说一下。
你可以按值传递一个数组,但你必须先把它包在一个结构或类中。 或者干脆使用std::vector这样的类型。
我想这个决定是为了提高效率。 人们在大多数时候都不想这么做。 这和为什么没有无符号双数的道理是一样的。 没有相关的CPU指令,所以在C++这样的语言中,你必须把效率不高的事情做得非常困难。
就像@litb提到的。"C++1x和boost都将原生数组封装到结构中,提供了std: :array和boost: :array,我一直比较喜欢,因为它允许在结构中传递和返回数组"
数组是指向存放该数组的内存和大小的指针。 注意,它和指向数组第一个元素的指针不完全一样。
大多数人认为必须将数组作为一个指针传递,并将大小作为一个单独的参数来指定,但这是不需要的。 你可以传递一个对实际数组本身的引用,同时保持它的sizeof()状态。
//Here you need the size because you have reduced
// your array to an int* pointing to the first element.
void test1(int *x, int size)
{
assert(sizeof(x) == 4);
}
//This function can take in an array of size 10
void test2(int (&x)[10])
{
assert(sizeof(x) == 40);
}
//Same as test2 but by pointer
void test3(int (*x)[10])
{
assert(sizeof(*x) == 40);
//Note to access elements you need to do: (*x)[i]
}
有些人可能会说,一个数组的大小是不知道的。 这是不对的。
int x[10];
assert(sizeof(x) == 40);
但是堆上的分配呢?堆上的分配不返回一个数组。 他们返回一个指向数组第一个元素的指针。 所以new不是类型安全的。 如果你确实有一个数组变量,那么你就会知道它所拥有的大小。
EDIT:我在下面留下了最初的答案,但我相信现在大部分的价值都在评论中。我已经把它做成了社区维基,所以如果有参与后续对话的人想编辑答案以反映这些信息,请随意。
原始答案
首先,它怎么知道要分配多少栈?对于结构体和对象来说,这是固定的(我相信),但是对于数组来说,这取决于数组有多大,而这要到执行时才知道。即使每个调用者在编译时都知道,也可能有不同的调用者使用不同的数组大小)。你可以在参数声明中强制要求一个特定的数组大小,但这似乎有点奇怪。
除此之外,正如Brian所说,还有效率的问题。
你想通过这一切达到什么目的?是想确保原始数组的内容不被改变吗?
我认为C语言中数组以指针形式传递而不是按值传递主要有3个原因。前2个原因在其他答案中已经提到了。
然而,我认为第三个原因是由于。
Dennis Ritchie讲述了C语言早期从BCPL和B等语言演变而来,特别是数组是如何实现的,它们是如何受到BCPL和B数组的影响,以及它们是如何和为什么不同的(而在表达式中仍然非常相似,因为数组名在表达式中衰减为指针)。
其实我不知道 任何 的语言,支持通过 赤裸裸 数组的值。这样做并不是特别有用,而且会很快地占用调用栈。
编辑。 致下线者--如果你知道更好的方法,请告诉我们大家。
这是那种 "只是因为 "的答案之一。C++从C语言中继承了它,并且不得不遵循它以保持兼容性。在C中这样做是为了提高效率。你很少会想在堆栈上复制一个大数组(记住,这里想想PDP-11)来传递给一个函数。