传递数组作为参考
在 C++ 中,当我在编译时不知道大小时,如何传递数组作为引用?到目前为止,我发现让它工作的唯一方法是使用类似的东西
const double( &numbers ) [size]
,但这意味着我需要在编译时知道数组的大小,因此我不能在外部函数。
我的问题是:
- 如果我不将数组作为
( const double( &numbers ) [length] )
传递,因为例如我不知道它的大小,如何我确保它不会被复制,但它被引用? - 如果我像上面的例子一样传递一个数组,
( double array[] )
它是引用还是复制?
In C++ how can I pass an array as a reference when I don't know the size at compile time? So far, I found out that the only way to make it work is to use something like
const double( &numbers ) [size]
but it means that I need to know the size of the array at compile time, thus I cannot use it in an external function.
My questions are:
- If I don't pass an array as a
( const double( &numbers ) [length] )
, because for example I don't know its size, how do I make sure that it doesn't get copied, but it is referenced? - If I pass an array like in the above example,
( double array[] )
is it referenced or is it copied?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
其他答案都很好,但没有人提到使用模板来处理这个问题。您仍然应该让您的函数采用指针和大小,但模板可以自动为您填充:
The other answers are great, but no one mention using templates to handle this. You should still make your function take a pointer and a size, but templates can fill that automatically for you:
在 C++ 中,您应该使用 std::vector。
在 C/C++ 中,不能将数组作为副本传递。数组始终通过引用传递。
编辑
在C++中,通过引用传递的数组具有不同的含义。在 C 和 C++ 中,数组都会衰减为指向数组第一个元素的指针。请检查下面的评论。
In C++, you should use std::vector.
In C/C++, you can't pass arrays as a copy. Arrays are always passed by reference.
EDIT
In C++, arrays passed by reference has different meaning. In both C and C++, arrays decay into a pointer to the first element of the array. Please check the comments below.
是的,这意味着您正在传递一个数组作为引用,
请注意,
长度
是一个常量整数。不,它没有被复制。这意味着您正在传递一个指向数组的指针,这相当于,
Yes, it means you're passing an array as reference,
Note that the
length
is a constant integer.No, it is not copied. It means you're passing a pointer to your array which is equivalent to,
有几件事:
C++ 无论如何都不允许可变大小的数组。因此,所有数组都需要在编译时具有已知的大小。因此,我不完全确定您最初的问题是否适用,因为您首先无法创建大小未知的数组。
当您传递数组时,它是通过引用完成的。它不会被复制。
无论如何,您可能会考虑使用
vector
。编辑:查看评论。
A couple things:
C++ doesn't allow variable-sized arrays anyway. So all your arrays will need to have known sizes at compile time. So I'm not entirely sure if your initial question is even applicable since you won't be able to make an array with an unknown size in the first place.
When you pass an array, it is done by reference. It is not copied.
In any case, you'll probably want to consider using
vector
instead.EDIT : See comments.
在 C++ 中,数组的名称只是指向其第一个元素的常量指针。 常量指针意味着一个指针能够改变它所指向的任何东西,但不能改变它指向其他东西。
这意味着每当您传递一个数组时,您实际上是在传递一个常量指针到该数组。换句话说,您已经通过引用传递了它,无需额外的努力。更准确地说,实际上复制的是常量指针,因此最终的(希望不是那么令人困惑的)措辞是您传递一个按值指向数组的常量指针。
如果您在编译时不知道数组的大小,只需使用指向数据类型的(普通)指针而不是显式数组。因此,无论
T my_array[]
是什么(其中T
是一种类型,例如int
、double
甚至是其中之一你的类)变成T* my_array
,并且此后的语法完全相同...my_array[i]
可以正常工作(也存在另一种语法,但不那么优雅)。对于初始化,请使用 new 运算符:或
其中 x 是整数(不一定像普通数组那样是常量)。这样你就可以在运行时从用户那里获取这个
x
,然后创建你的“数组”。使用完毕后请注意不要忘记delete[] my_array
,以避免内存泄漏。[最后说明] 仅当您确切知道需要多少个元素时,使用这样的动态分配数组才是一个不错的选择......无论是在编译时还是在运行时。因此,例如,如果在用户提供他的
x
之后,您将完全使用这些,那很好。否则,您将面临数组溢出的危险(如果您需要超过x
) - 这通常会导致应用程序崩溃 - 或者只是浪费一些空间。但即使是这种情况,您也将自己实现数组操作所需的大部分函数。这就是为什么最好使用 C++ 标准库提供的容器,例如std::vector
(如 Donotalo< /a> 提到)。我只是想进一步阐述这一点。In C++, an array's name is just a constant pointer to its first element. A constant pointer means a pointer that's capable of changing whatever it points to, but it can't be changed to point to something else.
This means that whenever you pass an array, you're actually passing a constant pointer to that array. In other words, you're already passing it by reference, no need for extra efforts. To be more accurate, what is actually copied is that constant pointer, so the final (hopefully not-that-confusing) phrasing is that you're passing a constant pointer to the array by value.
If you don't know your array's size at compile time, just use a (normal) pointer to your data type instead of an explicit array. So whatever is
T my_array[]
(whereT
is a type, likeint
,double
or even one of your classes) becomesT* my_array
, and the syntax is exactly the same hereafter...my_array[i]
will work fine (another syntax also exists, but not as elegant). For initialization, use thenew
operator:or
where
x
is an integer (not necessarily constant as is the case with normal arrays). This way you can take thisx
from the user at runtime and create your "array" then. Just take care not to forgetdelete[] my_array
after you finish using it to avoid memory leaks.[Final Note] Using such a dynamically allocated array is a good choice only when you know exactly how many elements you want... either at compile time or even at runtime. So, for example, if after the user supplies his
x
you'll exactly be using those, that's fine. Otherwise you're facing the danger of overflowing your array (if you need more thanx
) - which usually crashes the application - or just wasting some space. But even if this is the case, you'll implement most of the functions you need for array manipulation yourself. That's why it's preferable to use containers provided by the C++ Standard Library, likestd::vector
(as Donotalo mentioned). I just wanted to elaborate on that point more.其他语言(例如 Java 和 Python)确实在运行时存储数组的长度。在 C++ 数组中,不存储数组的长度。这意味着您需要手动将其存储在某个地方。
每当代码中有固定大小的数组时,编译器就会知道数组的大小,因为它是从源代码本身读取数组的。但是一旦代码被编译,长度信息就会丢失。例如:
编译器不会强制指定数组的大小。以下代码将静默编译,因为
f1
的数组参数只是指向数组第一个元素的指针:由于编译器在将数组传递给函数时忽略数组的静态大小,因此唯一的方法是:您必须知道作为引用传递的任意大小的数组的大小的方法是显式声明大小:
然后您可以使用任何数组调用该函数:
参数
array_size
包含数组的实际大小。请注意,
sizeof(array)
仅适用于静态定义的数组。当您将该数组传递给另一个函数时,大小信息将丢失。数组与指针不同。但是,像
f2
的参数这样的未定义大小的数组只是指向序列中第一个double
元素的指针:对于任何实际目的,
f2
code> 和f3
是等效的。这正是 std::vector 的工作原理。在内部,向量是一个具有两个字段的类:指向第一个元素的指针和向量中元素的数量。当您想要接受任意大小的数组作为参数时,这会使事情变得更简单:
Other languages like Java and Python do store the length of arrays at runtime. In C++ arrays, the length of the array is not stored. That means you need to store it manually somewhere.
Whenever you have a fixed size array on your code, the compiler knows the size of the array since it is reading it from the source code itself. But once the code get compiled, that length information is lost. For example:
The compiler won't enforce the size of the array. The following code will silently compile since the array parameter of
f1
us just a pointer to the first element of an array:Since the compiler ignores the static size of the array when passing it to a function, the only way you have to know the size of an arbitrarily sized array passed as a reference is to explicitly state the size:
Then you can call that function with any array:
The parameter
array_size
contains the actual size of the array.As a note,
sizeof(array)
only works on statically defined arrays. When you pass that array to another functions, the size information is lost.An array is not the same as a pointer. However, an array of undefined size like the parameter of
f2
is just a pointer to the firstdouble
element in the sequence:For any practicar purpose,
f2
andf3
are equivalent.This is exactly how
std::vector
works. Internally, a vector is a class with two fields: a pointer to the first element, and the number of elements in the vector. This makes things a little simpler when you want to accept an array of any size as a parameter: