简体   繁体   English

将数组传递给函数-指针与引用(C ++与C)

[英]Passing Array Into Function - Pointer vs Reference (C++ vs C)

I have a broad level question regarding best practices for passing arrays into functions. 关于将数组传递给函数的最佳实践,我有一个广泛的问题。

So in the past when I've been programming in C and I wanted a function to have it's input be an array, I would declare that functions input parameters to be a pointer. 所以在过去,当我使用C进行编程时,我希望一个函数将其输入作为数组,我会声明函数的输入参数为指针。 This worked relatively well. 这工作得比较好。

However, I've began programming more in C++ and am trying to determine the best practice for passing arrays into functions. 但是,我已经开始使用C ++进行更多编程,并试图确定将数组传递给函数的最佳实践。 So I've noticed that it is popular in C++ to pass objects by reference such that expensive copying operations are avoided. 因此,我注意到在C ++中流行通过引用传递对象,从而避免了昂贵的复制操作。 However, when I google passing arrays into functions, I read statements saying that arrays are automatically passed by reference.... So what's the deal with this? 但是,当我在Google中将数组传递给函数时,我读了一些语句,说数组是通过引用自动传递的。...那么,这有什么用呢? Why are arrays automatically passed by reference? 为什么数组通过引用自动传递? And let's say I don't want the function to modify the array, is it possible to pass const arrays? 假设我不希望函数修改数组,是否可以传递const数组?

I'm having a difficult time getting my test program to compile. 我很难编译我的测试程序。 So I'm curious if anyone could explain what it means to pass an array into a function in C++ and how that differs from C. 因此,我很好奇是否有人可以解释将数组传递给C ++中的函数的含义以及它与C有何不同。

Thanks! 谢谢!

In both C and C++, declaring a function to take an array parameter, such as in the following example, in fact causes the function to take a pointer. 在C和C ++中,声明一个函数采用数组参数,例如下面的示例,实际上使该函数采用指针。 For example: 例如:

void foo(int arr[]);

This function signature is identical to: 此功能签名与:

void foo(int *arr);

Thus when you try to pass an array in either C or C++ you're already avoiding any overhead of copying an array. 因此,当您尝试使用C或C ++传递数组时,已经避免了复制数组的任何开销。

Why are arrays automatically passed by reference? 为什么数组通过引用自动传递?

They're passed by reference only in a loose sense. 它们仅在宽松的意义上通过引用传递。 They're not literally passed as a C++ reference, which would look like the following: 它们实际上没有作为C ++参考传递,如下所示:

void foo(int (&arr)[10]); // arr is a reference to an array of 10 ints

The reason for the C behavior is because they thought passing arrays by value would never be used anyway because of the expensive copy. C行为的原因是因为他们认为由于昂贵的副本,无论如何都不会使用按值传递数组。 The reason C++ has the same behavior is simply for compatibility. C ++具有相同行为的原因仅仅是为了兼容性。

Experience has shown that the special behavior of array parameters was a bad idea, and so it is one of the many reason that one should avoid using raw arrays in C++. 经验表明,数组参数的特殊行为不是一个好主意,因此这是应避免在C ++中使用原始数组的众多原因之一。 The problem is that passing an array either way is dangerous: 问题在于,以任何一种方式传递数组都是危险的:

void foo(int arr[10]) { arr[9] = 0; }

void bar() {
    int data[] = {1, 2};
    foo(data);
}

The above code is wrong but the compiler thinks everything is fine and issues no warning about the buffer overrun. 上面的代码是错误的,但是编译器认为一切都很好,并且不发出有关缓冲区溢出的警告。

Instead use std::array or std::vector , which have consistent value semantics and lack any 'special' behavior that produces errors like the above. 取而代之的是使用std::arraystd::vector ,它们具有一致的值语义,并且没有任何会产生上述错误的“特殊”行为。

And let's say I don't want the function to modify the array, is it possible to pass const arrays? 假设我不希望函数修改数组,是否可以传递const数组?

You can: 您可以:

void foo(int const arr[]);
void foo(int const *arr);

void foo(int const (&arr)[10]);

So I'm curious if anyone could explain what it means to pass an array into a function in C++ and how that differs from C. 因此,我很好奇是否有人可以解释将数组传递给C ++中的函数的含义以及它与C有何不同。

If you use the syntax that works in C then it doesn't really differ at all. 如果您使用在C语言中有效的语法,那么它实际上并没有什么不同。

Best practice in C++ is to not use C-style arrays at all. C ++的最佳实践是根本不使用C样式的数组。

In C++, C-style arrays can be passed the same as they were in C. This could be described as passing the contents of the array by reference, because the function can modify the caller's array by indirecting through the pointer passed. 在C ++中,可以像在C中一样传递C样式的数组。这可以描述为通过引用传递数组的内容,因为该函数可以通过通过传递的指针进行间接修改调用者的数组。

In C++, if you really do want to use C-style arrays, you can choose between passing by pointer (as in C), and passing by using a C++ reference ( see here for example). 在C ++中,如果您确实想使用C样式的数组,则可以在通过指针传递(如在C中)和使用C ++引用传递之间进行选择(例如, 请参见此处 )。

In C++ best practice is to allow your arrays to be managed by containers, either std::array (compile time fixed) or std::vector (runtime variable). C++最佳实践是允许使用std :: array (固定的编译时间)或std :: vector (运行时变量)的容器来管理数组

Typically, if you don't want the array modified you will pass by const reference : 通常,如果您不希望修改数组,则可以通过const引用传递:

void func(const std::vector<int>& v); // pass by const reference

Otherwise, to modify the array in the function pass by normal reference: 否则,要修改函数中的数组,请通过常规引用传递:

void func(std::vector<int>& v); // pass by reference

More sophisticated and generic is to pass iterators to your function so that it can operate upon the entire array or just a part of it. 更复杂和通用的方法是将迭代器传递给函数,以便它可以对整个数组或仅对数组的一部分进行操作。

template<typename Iterator>
void func(Iterator begin, Iterator end);

That will be called like: 这将被称为:

func(v.begin(), v.end()); // operate on the whole array

Containers, iterators and algorithms (iterator based processing) have virtually eliminated the need for managing the array yourself. 容器,迭代器和算法 (基于迭代器的处理)实际上消除了自行管理阵列的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM