0

我在 C++ 中有一个关于返回数组的语法问题。当我们传入一个数组时,什么时候可以这样做:

void merge_sort(int input_array[], int size);//notice the first parameter

我知道这有效:

int* merge_sort(int input_array[], int size){
    //do something with input_array
    return new int[2]; //dummy array
}

问题:

int[] merge_sort(int input_array[], int size){ //Question is on return type, wont compile
     //do something with input_array
    return new int[2]; //dummy array
}

返回 int* 成功。为什么返回 int [] 失败?

4

3 回答 3

2

在 C 和 C++ 中,您既不能将数组作为参数传递给函数,也不能将数组作为函数结果返回。

是的,语法可以使它看起来像你在传递一个数组参数:

void func(int param[]) {
    // ...
}

...

int arr[10];
func(arr);

但实际上这只是将指针传递给数组的第一个元素。int param[]参数定义调整;它完全等同于int *param. 在大多数情况下,数组类型的表达式会隐式转换为其第一个元素的指针。

这就是为什么您需要将大小作为单独的参数传递。

仅使用 C 功能,有几种方法可以执行返回数组之类的操作:

  • 函数可以返回指向static数组第一个元素的指针。这有一些缺点:大小必须固定,并且多个调用者获得指向同一个对象的指针。
  • 函数可以接收由调用者传入的指向数组第一个元素的指针。这将分配和释放数组的负担放在调用者身上。
  • 函数可以返回指向动态分配(malloc()在 C 中,new在 C++ 中)数组的第一个元素的指针。这需要调用者释放数组。

C++ 提供了一组丰富的库类,可以为您处理所有这些问题。

推荐阅读: comp.lang.c FAQ的第 6 节。

可以将结构作为参数传递,并将它们作为函数结果返回,并且结构可以包含数组作为成员。但这并不像你想象的那么有用。作为结构成员的数组必须具有固定大小;对数组进行操作的最有用的代码可以处理动态大小。

于 2013-02-09T22:25:59.910 回答
1

你为什么要首先退回任何东西?

数组并没有真正“传递”给函数(没有复制元素),只有指向它开始的指针。当函数重新排列数组元素时,它是在原始数组中这样做的。函数退出后,调用代码可以简单地继续使用旧的(现在排序的)数组。

换句话说,该函数会产生副作用。

我知道这有效:

int* merge_sort(int input_array[], int size){
    //do something with input_array
    return new int[2]; //dummy array
}

(假设您实际上需要返回......)

好吧,它“有效”,但非常危险。调用者需要知道它需要释放返回的数组(否则会发生内存泄漏),并且它需要知道它必须使用delete[]而不仅仅是delete(否则会出现未定义的行为),这显然仅基于返回类型(它只是一个指针)。调用者也可能怀疑 是否在input_array函数内部被释放。

即使您已经记录了所有这些,调用者也很容易出错。使用现代 C++ 提供的工具会更好:例如,您可以返回一个std::vector.

于 2013-02-09T22:07:11.930 回答
0

您应该在这种方法中使用向量,在您的项目中包含然后几乎像使用数组一样使用向量。

您可以在这里查看向量:http: //msdn.microsoft.com/en-us/library/vstudio/9xd04bzs.aspx

矢量的好处是它们可以为您的项目动态缩放,并且不会由于缓冲区溢出而造成任何内存泄漏等,它很像 ArrayList

于 2013-02-10T00:59:31.847 回答