为什么c++不支持返回数组的函数?

时间:2022-01-20 01:15:54

Some languages enable you to just declare a function returning an array like a normal function, like Java:

有些语言使您可以声明一个函数,返回一个像普通函数一样的数组,比如Java:

public String[] funcarray() {
   String[] test = new String[]{"hi", "hello"};
   return test;
}

Why doesn't C++ support something like int[] funcarray(){} ? You can return an array, but it's a real hassle to make such a function. And also, I heard somewhere that strings are just arrays of char. So if you can return a string in C++, why not an array?

为什么c++不支持int[] funcarray(){}之类的东西?您可以返回一个数组,但是创建这样一个函数确实很麻烦。还有,我听说字符串是char的数组。如果你可以用c++返回一个字符串,为什么不能返回一个数组呢?

9 个解决方案

#1


54  

I'd wager a guess that to be concise, it was simply a design decision. More specifically, if you really want to know why, you need to work from the ground up.

我敢打赌,为了简洁起见,这只是一个设计决定。更具体地说,如果你真的想知道为什么,你需要从头开始工作。

Let's think about C first. In the C language, there is a clear distinction between "pass by reference" and "pass by value". To treat it lightly, the name of an array in C is really just a pointer. For all intents and purposes, the difference (generally) comes down to allocation. The code

首先考虑C。在C语言中,“pass by reference”和“pass by value”之间有明显的区别。简单地说,C中的数组的名称实际上只是一个指针。对于所有意图和目的,差异(通常)归结为分配。的代码

int array[n];

would create 4*n bytes of memory (on a 32 bit system) on the stack correlating to the scope of whichever code block makes the declaration. In turn,

将在堆栈上创建4*n字节的内存(在32位系统上),与声明的代码块的范围相关。反过来,

int* array = (int*) malloc(sizeof(int)*n);

would create the same amount memory, but on the heap. In this case, what is in that memory isn't tied to the scope, only the reference TO the memory is limited by the scope. Here's where pass by value and pass by reference come in. Passing by value, as you probably know, means that when something is passed in to or returned from a function, the "thing" that gets passed is the result of evaluating the variable. In other words,

将创建相同数量的内存,但是在堆上。在这种情况下,内存中的内容并不与范围绑定,只有对内存的引用受范围的限制。这里是传递值和传递引用的地方。传递值,正如您可能知道的那样,意味着当某些东西从函数中传入或返回时,传递的“东西”就是对变量求值的结果。换句话说,

int n = 4;
printf("%d", n);

will print the number 4 because the construct n evaluates to 4 (sorry if this is elementary, I just want to cover all the bases). This 4 has absolutely no bearing or relationship to the memory space of your program, it's just a literal, and so once you leave the scope in which that 4 has context, you lose it. What about pass by reference? Passing by reference is no different in the context of a function; you simply evaluate the construct that gets passed. The only difference is that after evaluating the passed "thing", you use the result of the evaluation as a memory address. I once had a particular cynical CS instructor who loved to state that there is no such thing as passing by reference, just a way to pass clever values. Really, he's right. So now we think about scope in terms of a function. Pretend that you can have an array return type:

打印数字4,因为构造n等于4(抱歉,如果这是基本的,我只是想覆盖所有的基)。这个4和你的程序的内存空间完全没有关系,它只是一个文字,所以一旦你离开了这个4有上下文的范围,你就失去了它。通过引用怎么样?在函数的上下文中,通过引用并没有什么不同;您只需对传递的构造进行评估。惟一的区别是,在评估传递的“东西”之后,您将评估结果用作内存地址。我曾经有过一个特别愤世嫉俗的CS讲师,他喜欢说没有所谓的“传递参考”,只是传递聪明价值观的一种方式。真的,他是对的。现在我们考虑作用域。假设您可以有一个数组返回类型:

int[] foo(args){
    result[n];
    // Some code
    return result;
}

The problem here is that result evaluates to the address of the 0th element of the array. But when you attempt to access this memory from outside of this function (via the return value), you have a problem because you are attempting to access memory that is not in the scope with which you are working (the function call's stack). So the way we get around this is with the standard "pass by reference" jiggery-pokery:

这里的问题是,结果计算到数组的第0个元素的地址。但是,当您试图从函数之外(通过返回值)访问该内存时,您遇到了一个问题,因为您正在尝试访问不在您正在使用的范围内的内存(函数调用的堆栈)。所以我们解决这个问题的方法是使用标准的"参照传递"

int* foo(args){
    int* result = (int*) malloc(sizeof(int)*n));
    // Some code
    return result;
}

We still get a memory address pointing to the 0th element of the Array, but now we have access to that memory.

我们仍然得到一个指向数组第0个元素的内存地址,但是现在我们可以访问那个内存。

What's my point? In Java, it is common to assert that "everything is pass by value". This is true. The same cynical instructor from above also had this to say about Java and OOP in general: Everything is just a pointer. And he's also right. While everything in Java is in fact pass by value, almost all of those values are actually memory addresses. So in Java, the language does let you return an array or a String, but it does so by turning it in to the version with pointers for you. It also manages your memory for you. And automatic memory management, while helpful, is not efficient.

我的观点是什么?在Java中,断言“一切都通过值传递”是很常见的。这是正确的。同样,上面那位愤世嫉俗的讲师对Java和OOP也有这样的看法:一切都只是一个指针。他也是对的。虽然Java中的所有值实际上都是通过值传递的,但几乎所有这些值实际上都是内存地址。所以在Java中,语言确实允许你返回一个数组或一个字符串,但是它通过为你提供指针的版本来实现。它也为你管理你的记忆。自动内存管理虽然有帮助,但并不有效。

This brings us to C++. The whole reason C++ was invented was because Bjarne Stroustrup had been experimenting with Simula (basically the original OOPL) during his PhD work, and thought it was fantastic conceptually, but he noticed that it performed rather terribly. And so he began working on what was called C with Classes, which got renamed to C++. In doing so, his goal was to make a programming language that took SOME of the best features from Simula but remained powerful and fast. He chose to extend C due to its already legendary performance, and one tradeoff was that he chose to not implement automatic memory management or garbage collecting on such a large scale like other OOPL's. Returning an array from one of the template classes works because, well, you're using a class. But if you want to return a C array, you have to do it the C way. In other words, C++ does support returning an array EXACTLY the same way that Java does; it just doesn't do all of the work for you. Because a Danish dude thought it'd be too slow.

这就涉及到c++。c++之所以被发明,是因为Bjarne Stroustrup在他的博士论文中一直在试验Simula(基本上是原始的OOPL),他认为它在概念上很神奇,但他注意到它表现得相当糟糕。于是他开始研究所谓的C语言,它被重新命名为c++。在这样做的过程中,他的目标是开发一种编程语言,它采用了Simula中一些最好的特性,但仍然强大而快速。他选择扩展C是因为它已经具有传奇的性能,而且他选择不像其他OOPL那样大规模地实现自动内存管理或垃圾收集。从模板类中返回一个数组是有效的,因为您正在使用一个类。但是如果你想返回一个C数组,你必须用C方法。换句话说,c++确实支持返回与Java完全相同的数组;它不会为你做所有的工作。因为一个丹麦人觉得太慢了。

#2


31  

C++ does support it - well sort of:

c++确实支持它——嗯,有点:

vector< string> func()
{
   vector<string> res;
   res.push_back( "hello" );
   res.push_back( "world" );
   return res;
}

Even C sort-of supports it:

甚至C类的支持:

struct somearray
{
  struct somestruct d[50];
};

struct somearray func()
{
   struct somearray res;
   for( int i = 0; i < 50; ++i )
   {
      res.d[i] = whatever;
   }
   // fill them all in
   return res;
}

A std::string is a class but when you say a string you probably mean a literal. You can return a literal safely from a function but actually you could statically create any array and return it from a function. This would be thread-safe if it was a const (read-only) array which is the case with string literals.

string是一个类,但是当你说string时,你可能指的是文字。可以从函数中安全地返回文字,但实际上可以静态地创建任何数组并从函数中返回。如果是const(只读)数组,这将是线程安全的。

The array you return would degrade to a pointer though, so you would not be able to work out its size just from its return.

不过,返回的数组会降级为指针,因此仅从返回就无法计算它的大小。

Returning an array, if it were possible, would have to be fixed length in the first place, given that the compiler needs to create the call stack, and then has the issue that arrays are not l-values so receiving it in the calling function would have to use a new variable with initialisation, which is impractical. Returning one may be impractical too for the same reason, atlhough they might have used a special notation for return values.

返回一个数组,如果它是可能的,首先必须固定长度,考虑到编译器需要创建调用堆栈,然后有数组的问题不是l-values因此收到它在调用函数必须使用一个新的变量初始化,这是不切实际的。返回一个可能也是不切实际的,因为同样的原因,atlhough他们可能会用一个特殊的符号来表示返回值。

Remember in the early days of C all the variables had to be declared at the top of the function and you couldn't just declare at first use. Thus it was infeasible at the time.

记住,在C的早期,所有的变量都必须在函数的顶部声明,你不能在第一次使用时声明。因此,这在当时是不可行的。

They gave the workaround of putting the array into a struct and that is just how it now has to remain in C++ because it uses the same calling convention.

他们给出了将数组放入struct的方法,这就是它现在必须保持在c++中的原因,因为它使用相同的调用约定。

Note: In languages like Java, an array is a class. You create one with new. You can reassign them (they are l-values).

注意:在Java等语言中,数组是类。你用新的创建一个。你可以重新分配它们(它们是l值)。

#3


25  

Arrays in C (and in C++ for backwards compatibility) have special semantics that differ from the rest of the types. In particular, while for the rest of the types, C only has pass-by-value semantics, in the case of arrays the effect of the pass-by-value syntax simulates pass-by-reference in a strange way:

C中的数组(以及c++中用于向后兼容性的数组)具有与其他类型不同的特殊语义。特别是,对于其余的类型,C仅具有按值传递语义,对于数组,按值传递语法的效果以一种奇怪的方式模拟了按值传递:

In a function signature, an argument of type array of N elements of type T gets converted to pointer to T. In a function call passing an array as argument to a function will decay the array to a pointer to the first element, and that pointer is copied into the function.

函数签名,一个N个元素的数组类型的参数T被转换为指针类型T的函数调用将数组作为参数传递给一个函数将衰变数组第一个元素的指针,这个指针复制到函数。

Because of this particular treatment for arrays --they cannot be passed by value--, they cannot be returned by value either. In C you can return a pointer, and in C++ you can also return a reference, but the array itself cannot be allocated in the stack.

由于数组的这种特殊处理——它们不能通过值传递——它们也不能通过值返回。在C中可以返回一个指针,在c++中也可以返回一个引用,但是数组本身不能在堆栈中分配。

If you think of it, this is not different from the language that you are using in the question, as the array is dynamically allocated and you are only returning a pointer/reference to it.

如果你想一下,这和你在问题中使用的语言没有什么不同,因为数组是动态分配的,你只返回一个指针/引用。

The C++ language, on the other hand, enables different solutions to that particular problem, like using std::vector in the current standard (contents are dynamically allocated) or std::array in the upcoming standard (contents can be allocated in the stack, but it might have a greater cost, as each element will have to be copied in those cases where the copy cannot be elided by the compiler). In fact, you can use the same type of approach with the current standard by using off-the-shelf libraries like boost::array.

c++语言,另一方面,允许不同的解决特定问题,喜欢用std::向量在当前标准(内容是动态分配的)或std::数组在即将到来的标准(内容可以分配在堆栈中,但它可能有一个更大的成本,因为每个元素必须被复制在这些情况下,副本由编译器不能省略)。实际上,通过使用boost::array等现成库,您可以使用与当前标准相同的方法。

#4


8  

"You can't return array from the function because that array would be declared inside the function, and its location would then be the stack frame. However, stack frame is erased when function exits. Functions must copy return value from stack frame to return location, and that's not possible with arrays."

不能从函数中返回数组,因为数组将在函数中声明,它的位置将是堆栈帧。但是,当函数退出时,堆栈帧被擦除。函数必须将返回值从堆栈帧复制到返回位置,这对数组来说是不可能的。

From a discussion here:

从一个讨论:

http://forum.codecall.net/c-c/32457-function-return-array-c.html

http://forum.codecall.net/c-c/32457-function-return-array-c.html

#5


7  

Other have said that in C++, one use vector<> instead of the arrays inherited from C.

还有人说,在c++中,使用向量<>而不是从C继承的数组。

So why C++ doesn't allows to returns C arrays? Because C doesn't.

那么为什么c++不允许返回C数组呢?因为C没有。

Why C doesn't? Because C evolved from B, a untyped language in which returning an array doesn't make sense at all. When adding types to B, it would have been meaningful to make it possible to return an array but that wasn't done in order to keep some B idioms valid and ease the conversion of programs from B to C. And since then, the possibility of making C arrays more usable as always been refused (and even more, not even considered) as it would break too much existing code.

为什么不?因为C是从B进化而来的,所以返回数组的非类型化语言一点意义都没有。当添加类型B,这将是有意义的,让它可以返回一个数组,但没有完成为了保持一些B习语的有效和易于转换程序从B到C,从那时起,使C数组更可用的可能性总是被拒绝(甚至更多,甚至不考虑),因为它会破坏现有代码太多了。

#6


3  

You can return a pointer to the array. Just be careful about releasing the memory later.

可以返回指向数组的指针。以后释放记忆时要小心。

public std::string* funcarray() {
    std::string* test = new std::string[2];
    test[0] = "hi";
    test[1] = "hello";
    return test;
}

// somewhere else:
std::string* arr = funcarray();
std::cout << arr[0] << " MisterSir" << std::endl;
delete[] arr;

Or you can just use one of the containers in the std namespace, like std::vector.

或者您可以使用std名称空间中的一个容器,比如std::vector。

#7


2  

"Why doesn't C++ support something like": Because it would not make any sense. In reference-based languages like JAVA or PHP, memory management is based on garbage collection. The portions of memory which have no references (no variable in your program points to it any more) is automatically freed. In this context you can allocate memory, and pass the reference around carefreely.

“为什么c++不支持类似的东西”:因为它没有任何意义。在基于引用的语言(如JAVA或PHP)中,内存管理基于垃圾收集。没有引用(程序中不再有变量指向它)的内存部分将自动释放。在这种情况下,您可以分配内存,并*地传递引用。

C++ code will be translated to machine code, and there is no GC defined in it. So in C and C++ there is a strong sense of ownership of memory blocks. You have to know if the pointer you go is yours to free at any time (in fact you shoud free it after use), or you have a pointer to a shared portion of memory, which is an absolute no-no to free.

c++代码将被翻译成机器码,并且其中没有定义GC。因此,在C和c++中,有一种强烈的内存块所有权意识。你必须知道你要释放的指针是否在任何时候都是你的(事实上你应该在使用后释放它),或者你有一个指向内存共享部分的指针,这是绝对不允许释放的。

In this environment you would win nothing with cretaing endless copies of an array every time it passes to and from a function. It is amuch more complex task to manage your arrays of data in c-like languages. There is no one-size-fits-all solution, and you need to know when to free memory.

在这个环境中,每当它从一个函数传递到一个数组时,就不会得到一个数组的无数副本。用类c语言管理数据数组是一项非常复杂的任务。没有一种通用的解决方案,你需要知道什么时候释放内存。

Would an array returned by a function always be a copy (yours to free) or you have to make copies of them? Whet would you win by getting an array insted of a pointer to an array?

一个函数返回的数组总是一个副本(您的是免费的)还是必须复制它们?如果你得到一个指向数组的指针的数组,你会赢吗?

#8


1  

Return a std::vector<> instead of an array. In general, arrays do not work well with C++, and should generally be avoided.

返回一个std::vector<>而不是数组。通常,数组在c++中不能很好地工作,通常应该避免。

Also, the string datatype is not just an array of characters, although a "quoted string" is. The string manages an array of characters, and you can get access to it with .c_str(), but there's more to a string than that.

此外,字符串数据类型不仅仅是一个字符数组,尽管“引用字符串”是。这个字符串管理一个字符数组,您可以使用.c_str()访问它,但是一个字符串不止这些。

#9


1  

Check out here. Really helpful.

看看这里。真的有帮助。

#1


54  

I'd wager a guess that to be concise, it was simply a design decision. More specifically, if you really want to know why, you need to work from the ground up.

我敢打赌,为了简洁起见,这只是一个设计决定。更具体地说,如果你真的想知道为什么,你需要从头开始工作。

Let's think about C first. In the C language, there is a clear distinction between "pass by reference" and "pass by value". To treat it lightly, the name of an array in C is really just a pointer. For all intents and purposes, the difference (generally) comes down to allocation. The code

首先考虑C。在C语言中,“pass by reference”和“pass by value”之间有明显的区别。简单地说,C中的数组的名称实际上只是一个指针。对于所有意图和目的,差异(通常)归结为分配。的代码

int array[n];

would create 4*n bytes of memory (on a 32 bit system) on the stack correlating to the scope of whichever code block makes the declaration. In turn,

将在堆栈上创建4*n字节的内存(在32位系统上),与声明的代码块的范围相关。反过来,

int* array = (int*) malloc(sizeof(int)*n);

would create the same amount memory, but on the heap. In this case, what is in that memory isn't tied to the scope, only the reference TO the memory is limited by the scope. Here's where pass by value and pass by reference come in. Passing by value, as you probably know, means that when something is passed in to or returned from a function, the "thing" that gets passed is the result of evaluating the variable. In other words,

将创建相同数量的内存,但是在堆上。在这种情况下,内存中的内容并不与范围绑定,只有对内存的引用受范围的限制。这里是传递值和传递引用的地方。传递值,正如您可能知道的那样,意味着当某些东西从函数中传入或返回时,传递的“东西”就是对变量求值的结果。换句话说,

int n = 4;
printf("%d", n);

will print the number 4 because the construct n evaluates to 4 (sorry if this is elementary, I just want to cover all the bases). This 4 has absolutely no bearing or relationship to the memory space of your program, it's just a literal, and so once you leave the scope in which that 4 has context, you lose it. What about pass by reference? Passing by reference is no different in the context of a function; you simply evaluate the construct that gets passed. The only difference is that after evaluating the passed "thing", you use the result of the evaluation as a memory address. I once had a particular cynical CS instructor who loved to state that there is no such thing as passing by reference, just a way to pass clever values. Really, he's right. So now we think about scope in terms of a function. Pretend that you can have an array return type:

打印数字4,因为构造n等于4(抱歉,如果这是基本的,我只是想覆盖所有的基)。这个4和你的程序的内存空间完全没有关系,它只是一个文字,所以一旦你离开了这个4有上下文的范围,你就失去了它。通过引用怎么样?在函数的上下文中,通过引用并没有什么不同;您只需对传递的构造进行评估。惟一的区别是,在评估传递的“东西”之后,您将评估结果用作内存地址。我曾经有过一个特别愤世嫉俗的CS讲师,他喜欢说没有所谓的“传递参考”,只是传递聪明价值观的一种方式。真的,他是对的。现在我们考虑作用域。假设您可以有一个数组返回类型:

int[] foo(args){
    result[n];
    // Some code
    return result;
}

The problem here is that result evaluates to the address of the 0th element of the array. But when you attempt to access this memory from outside of this function (via the return value), you have a problem because you are attempting to access memory that is not in the scope with which you are working (the function call's stack). So the way we get around this is with the standard "pass by reference" jiggery-pokery:

这里的问题是,结果计算到数组的第0个元素的地址。但是,当您试图从函数之外(通过返回值)访问该内存时,您遇到了一个问题,因为您正在尝试访问不在您正在使用的范围内的内存(函数调用的堆栈)。所以我们解决这个问题的方法是使用标准的"参照传递"

int* foo(args){
    int* result = (int*) malloc(sizeof(int)*n));
    // Some code
    return result;
}

We still get a memory address pointing to the 0th element of the Array, but now we have access to that memory.

我们仍然得到一个指向数组第0个元素的内存地址,但是现在我们可以访问那个内存。

What's my point? In Java, it is common to assert that "everything is pass by value". This is true. The same cynical instructor from above also had this to say about Java and OOP in general: Everything is just a pointer. And he's also right. While everything in Java is in fact pass by value, almost all of those values are actually memory addresses. So in Java, the language does let you return an array or a String, but it does so by turning it in to the version with pointers for you. It also manages your memory for you. And automatic memory management, while helpful, is not efficient.

我的观点是什么?在Java中,断言“一切都通过值传递”是很常见的。这是正确的。同样,上面那位愤世嫉俗的讲师对Java和OOP也有这样的看法:一切都只是一个指针。他也是对的。虽然Java中的所有值实际上都是通过值传递的,但几乎所有这些值实际上都是内存地址。所以在Java中,语言确实允许你返回一个数组或一个字符串,但是它通过为你提供指针的版本来实现。它也为你管理你的记忆。自动内存管理虽然有帮助,但并不有效。

This brings us to C++. The whole reason C++ was invented was because Bjarne Stroustrup had been experimenting with Simula (basically the original OOPL) during his PhD work, and thought it was fantastic conceptually, but he noticed that it performed rather terribly. And so he began working on what was called C with Classes, which got renamed to C++. In doing so, his goal was to make a programming language that took SOME of the best features from Simula but remained powerful and fast. He chose to extend C due to its already legendary performance, and one tradeoff was that he chose to not implement automatic memory management or garbage collecting on such a large scale like other OOPL's. Returning an array from one of the template classes works because, well, you're using a class. But if you want to return a C array, you have to do it the C way. In other words, C++ does support returning an array EXACTLY the same way that Java does; it just doesn't do all of the work for you. Because a Danish dude thought it'd be too slow.

这就涉及到c++。c++之所以被发明,是因为Bjarne Stroustrup在他的博士论文中一直在试验Simula(基本上是原始的OOPL),他认为它在概念上很神奇,但他注意到它表现得相当糟糕。于是他开始研究所谓的C语言,它被重新命名为c++。在这样做的过程中,他的目标是开发一种编程语言,它采用了Simula中一些最好的特性,但仍然强大而快速。他选择扩展C是因为它已经具有传奇的性能,而且他选择不像其他OOPL那样大规模地实现自动内存管理或垃圾收集。从模板类中返回一个数组是有效的,因为您正在使用一个类。但是如果你想返回一个C数组,你必须用C方法。换句话说,c++确实支持返回与Java完全相同的数组;它不会为你做所有的工作。因为一个丹麦人觉得太慢了。

#2


31  

C++ does support it - well sort of:

c++确实支持它——嗯,有点:

vector< string> func()
{
   vector<string> res;
   res.push_back( "hello" );
   res.push_back( "world" );
   return res;
}

Even C sort-of supports it:

甚至C类的支持:

struct somearray
{
  struct somestruct d[50];
};

struct somearray func()
{
   struct somearray res;
   for( int i = 0; i < 50; ++i )
   {
      res.d[i] = whatever;
   }
   // fill them all in
   return res;
}

A std::string is a class but when you say a string you probably mean a literal. You can return a literal safely from a function but actually you could statically create any array and return it from a function. This would be thread-safe if it was a const (read-only) array which is the case with string literals.

string是一个类,但是当你说string时,你可能指的是文字。可以从函数中安全地返回文字,但实际上可以静态地创建任何数组并从函数中返回。如果是const(只读)数组,这将是线程安全的。

The array you return would degrade to a pointer though, so you would not be able to work out its size just from its return.

不过,返回的数组会降级为指针,因此仅从返回就无法计算它的大小。

Returning an array, if it were possible, would have to be fixed length in the first place, given that the compiler needs to create the call stack, and then has the issue that arrays are not l-values so receiving it in the calling function would have to use a new variable with initialisation, which is impractical. Returning one may be impractical too for the same reason, atlhough they might have used a special notation for return values.

返回一个数组,如果它是可能的,首先必须固定长度,考虑到编译器需要创建调用堆栈,然后有数组的问题不是l-values因此收到它在调用函数必须使用一个新的变量初始化,这是不切实际的。返回一个可能也是不切实际的,因为同样的原因,atlhough他们可能会用一个特殊的符号来表示返回值。

Remember in the early days of C all the variables had to be declared at the top of the function and you couldn't just declare at first use. Thus it was infeasible at the time.

记住,在C的早期,所有的变量都必须在函数的顶部声明,你不能在第一次使用时声明。因此,这在当时是不可行的。

They gave the workaround of putting the array into a struct and that is just how it now has to remain in C++ because it uses the same calling convention.

他们给出了将数组放入struct的方法,这就是它现在必须保持在c++中的原因,因为它使用相同的调用约定。

Note: In languages like Java, an array is a class. You create one with new. You can reassign them (they are l-values).

注意:在Java等语言中,数组是类。你用新的创建一个。你可以重新分配它们(它们是l值)。

#3


25  

Arrays in C (and in C++ for backwards compatibility) have special semantics that differ from the rest of the types. In particular, while for the rest of the types, C only has pass-by-value semantics, in the case of arrays the effect of the pass-by-value syntax simulates pass-by-reference in a strange way:

C中的数组(以及c++中用于向后兼容性的数组)具有与其他类型不同的特殊语义。特别是,对于其余的类型,C仅具有按值传递语义,对于数组,按值传递语法的效果以一种奇怪的方式模拟了按值传递:

In a function signature, an argument of type array of N elements of type T gets converted to pointer to T. In a function call passing an array as argument to a function will decay the array to a pointer to the first element, and that pointer is copied into the function.

函数签名,一个N个元素的数组类型的参数T被转换为指针类型T的函数调用将数组作为参数传递给一个函数将衰变数组第一个元素的指针,这个指针复制到函数。

Because of this particular treatment for arrays --they cannot be passed by value--, they cannot be returned by value either. In C you can return a pointer, and in C++ you can also return a reference, but the array itself cannot be allocated in the stack.

由于数组的这种特殊处理——它们不能通过值传递——它们也不能通过值返回。在C中可以返回一个指针,在c++中也可以返回一个引用,但是数组本身不能在堆栈中分配。

If you think of it, this is not different from the language that you are using in the question, as the array is dynamically allocated and you are only returning a pointer/reference to it.

如果你想一下,这和你在问题中使用的语言没有什么不同,因为数组是动态分配的,你只返回一个指针/引用。

The C++ language, on the other hand, enables different solutions to that particular problem, like using std::vector in the current standard (contents are dynamically allocated) or std::array in the upcoming standard (contents can be allocated in the stack, but it might have a greater cost, as each element will have to be copied in those cases where the copy cannot be elided by the compiler). In fact, you can use the same type of approach with the current standard by using off-the-shelf libraries like boost::array.

c++语言,另一方面,允许不同的解决特定问题,喜欢用std::向量在当前标准(内容是动态分配的)或std::数组在即将到来的标准(内容可以分配在堆栈中,但它可能有一个更大的成本,因为每个元素必须被复制在这些情况下,副本由编译器不能省略)。实际上,通过使用boost::array等现成库,您可以使用与当前标准相同的方法。

#4


8  

"You can't return array from the function because that array would be declared inside the function, and its location would then be the stack frame. However, stack frame is erased when function exits. Functions must copy return value from stack frame to return location, and that's not possible with arrays."

不能从函数中返回数组,因为数组将在函数中声明,它的位置将是堆栈帧。但是,当函数退出时,堆栈帧被擦除。函数必须将返回值从堆栈帧复制到返回位置,这对数组来说是不可能的。

From a discussion here:

从一个讨论:

http://forum.codecall.net/c-c/32457-function-return-array-c.html

http://forum.codecall.net/c-c/32457-function-return-array-c.html

#5


7  

Other have said that in C++, one use vector<> instead of the arrays inherited from C.

还有人说,在c++中,使用向量<>而不是从C继承的数组。

So why C++ doesn't allows to returns C arrays? Because C doesn't.

那么为什么c++不允许返回C数组呢?因为C没有。

Why C doesn't? Because C evolved from B, a untyped language in which returning an array doesn't make sense at all. When adding types to B, it would have been meaningful to make it possible to return an array but that wasn't done in order to keep some B idioms valid and ease the conversion of programs from B to C. And since then, the possibility of making C arrays more usable as always been refused (and even more, not even considered) as it would break too much existing code.

为什么不?因为C是从B进化而来的,所以返回数组的非类型化语言一点意义都没有。当添加类型B,这将是有意义的,让它可以返回一个数组,但没有完成为了保持一些B习语的有效和易于转换程序从B到C,从那时起,使C数组更可用的可能性总是被拒绝(甚至更多,甚至不考虑),因为它会破坏现有代码太多了。

#6


3  

You can return a pointer to the array. Just be careful about releasing the memory later.

可以返回指向数组的指针。以后释放记忆时要小心。

public std::string* funcarray() {
    std::string* test = new std::string[2];
    test[0] = "hi";
    test[1] = "hello";
    return test;
}

// somewhere else:
std::string* arr = funcarray();
std::cout << arr[0] << " MisterSir" << std::endl;
delete[] arr;

Or you can just use one of the containers in the std namespace, like std::vector.

或者您可以使用std名称空间中的一个容器,比如std::vector。

#7


2  

"Why doesn't C++ support something like": Because it would not make any sense. In reference-based languages like JAVA or PHP, memory management is based on garbage collection. The portions of memory which have no references (no variable in your program points to it any more) is automatically freed. In this context you can allocate memory, and pass the reference around carefreely.

“为什么c++不支持类似的东西”:因为它没有任何意义。在基于引用的语言(如JAVA或PHP)中,内存管理基于垃圾收集。没有引用(程序中不再有变量指向它)的内存部分将自动释放。在这种情况下,您可以分配内存,并*地传递引用。

C++ code will be translated to machine code, and there is no GC defined in it. So in C and C++ there is a strong sense of ownership of memory blocks. You have to know if the pointer you go is yours to free at any time (in fact you shoud free it after use), or you have a pointer to a shared portion of memory, which is an absolute no-no to free.

c++代码将被翻译成机器码,并且其中没有定义GC。因此,在C和c++中,有一种强烈的内存块所有权意识。你必须知道你要释放的指针是否在任何时候都是你的(事实上你应该在使用后释放它),或者你有一个指向内存共享部分的指针,这是绝对不允许释放的。

In this environment you would win nothing with cretaing endless copies of an array every time it passes to and from a function. It is amuch more complex task to manage your arrays of data in c-like languages. There is no one-size-fits-all solution, and you need to know when to free memory.

在这个环境中,每当它从一个函数传递到一个数组时,就不会得到一个数组的无数副本。用类c语言管理数据数组是一项非常复杂的任务。没有一种通用的解决方案,你需要知道什么时候释放内存。

Would an array returned by a function always be a copy (yours to free) or you have to make copies of them? Whet would you win by getting an array insted of a pointer to an array?

一个函数返回的数组总是一个副本(您的是免费的)还是必须复制它们?如果你得到一个指向数组的指针的数组,你会赢吗?

#8


1  

Return a std::vector<> instead of an array. In general, arrays do not work well with C++, and should generally be avoided.

返回一个std::vector<>而不是数组。通常,数组在c++中不能很好地工作,通常应该避免。

Also, the string datatype is not just an array of characters, although a "quoted string" is. The string manages an array of characters, and you can get access to it with .c_str(), but there's more to a string than that.

此外,字符串数据类型不仅仅是一个字符数组,尽管“引用字符串”是。这个字符串管理一个字符数组,您可以使用.c_str()访问它,但是一个字符串不止这些。

#9


1  

Check out here. Really helpful.

看看这里。真的有帮助。