假设我想在 C++ 中定义一个函数,比如
int sort( int a[n], int n)
我希望函数对没有预定义长度的数组进行操作。我该怎么做?
最惯用的方法是定义一个带有两个迭代器的函数:
template<typename Iter>
int sort(Iter first, Itera last);
在罗马时,像罗马人那样做(“罗马”= 标准库)。
你可以让你的函数成为一个模板来给你一个数组维度的句柄:
template <size_t N>
int mysort( int (&a)[N] )
{
/// access as a[n], where n is in range [0,N)
}
但更惯用的方法是传递两个迭代器,因为它也适用于标准库容器和动态大小的数组:
template<typename Iterator>
int mysort(Iterator begin, Iterator end) { ... }
然后
int arr[] = {1,54,3,7,9,87};
mysort(arr);
mysort(std::begin(arr), std::end(arr));
请记住,我将名称更改为是mysort
因为标准库有一个著名的算法,称为std::sort
.
编译器会忽略数组参数的大小,因为当您将数组传递给函数时,它会被转换为指针。实际上,
int sort( int a[], int n)
相当于
int sort( int* a, int n)
数组的大小直到运行时才知道,应该作为第二个参数传递。
你不能完全按照你的要求去做。我想最接近的是使用std::vector<int>
int sort(std::vector<int>& a)
{
...
}
std::vector
支持所有常见的数组操作(a[i]
等)加上更多,比如a.size()
获取向量的大小。
如果要使用该结构,则需要某种方法来确定数组的结尾。例如,作为 char 数组的字符串使用空终止符。如果您无法确定结构的结尾,您将无法安全地对其进行迭代。
指针方法将允许您迭代数组,但在迭代时您将无法安全地确定数组的结尾。
int sort( int* arr )
{
// do your sorting here
}
使用指针:
int sort(int* a, int n)
有一些标记数组结尾的元素。这就是大多数字符串操作的工作方式,字符串的结尾用 '\0' 标记。
理想情况下,您不会传递普通数组,而是传递一些更高级别的对象,例如 a std::vector
or std::array
。