Matriz de retorno en una función

212

Tengo una matriz int arr[5]que se pasa a una función fillarr(int arr[]):

int fillarr(int arr[])
{
    for(...);
    return arr;
}
  1. ¿Cómo puedo devolver esa matriz?
  2. ¿Cómo lo usaré? Digamos que devolví un puntero, ¿cómo voy a acceder?
Ismail Marmoush
fuente
46
Hablando estrictamente en este contexto, no necesita devolver la matriz, ya que la matriz se pasa por referencia, por lo que cualquier cambio en los elementos dentro de 'arr' se verá fuera de la función.
BuggerMe
12
devolver la matriz es conveniente para encadenar funciones.
Seand
55
Siempre y cuando no esté cometiendo el error de crear una matriz en la pila y devolverle un puntero.
detly
2
@ismail: no puede devolver una nueva matriz, a menos que esa matriz se haya asignado dinámicamente. Y si ese es el caso, úsalo std::vector.
GManNickG
44
@BuggerMe: Las matrices no se pasan por referencia (a menos que lo solicite con una sintaxis mucho más divertida), en el código, la matriz se desintegra en un puntero al primer elemento y eso se pasa a la función. El 5compilador descarta la firma en la función.
David Rodríguez - dribeas

Respuestas:

204

En este caso, su variable de matriz arrtambién puede tratarse como un puntero al comienzo del bloque de su matriz en la memoria, mediante una conversión implícita. Esta sintaxis que estás usando:

int fillarr(int arr[])

Es una especie de azúcar sintáctica. Realmente podría reemplazarlo con esto y aún funcionaría:

int fillarr(int* arr)

Entonces, en el mismo sentido, lo que desea devolver de su función es en realidad un puntero al primer elemento de la matriz:

int* fillarr(int arr[])

Y aún podrá usarlo como lo haría con una matriz normal:

int main()
{
  int y[10];
  int *a = fillarr(y);
  cout << a[0] << endl;
}
Brent escribe el código
fuente
45
Para aclarar, esa "declaración clásica de C ++" es falsa; Las matrices no son punteros.
GManNickG
25
recuerde la regla a [i] == * (a + i)
2010
8
@Brent Nash, no. Una matriz es una matriz. Un puntero al inicio de la matriz es un puntero. Simplemente sucede que el compilador tiene algo de azúcar sintáctico que hace la traducción por usted en algunas situaciones. arrayy &arrayson intercambiables en muchos casos.
Carl Norum
20
@Brent: No. Una matriz es de su propio tipo, no es un tipo especial de puntero. El tipo de aen int a[10]es int[10]. Lo que puede decir es que las matrices "decaen" en punteros a su primer elemento. (Esta es una conversión implícita de matriz a puntero). Entonces su respuesta iría en la misma línea que la mía. Si edita su respuesta para diferenciar entre matrices, conversión de matriz a puntero y punteros, eliminaré mi respuesta ya que tendrían la misma información central y usted fue el primero.
GManNickG
8
@seand recuerda la regla a [i] == * (a + sizeof (a) * i)
Amir
114

Las funciones de C ++ no pueden devolver matrices de estilo C por valor. Lo más cercano es devolver un puntero. Además, un tipo de matriz en la lista de argumentos simplemente se convierte en un puntero.

int *fillarr( int arr[] ) { // arr "decays" to type int *
    return arr;
}

Puede mejorarlo utilizando una matriz de referencias para el argumento y el retorno, lo que evita la descomposición:

int ( &fillarr( int (&arr)[5] ) )[5] { // no decay; argument must be size 5
    return arr;
}

Con Boost o C ++ 11, la referencia de paso solo es opcional y la sintaxis es menos alucinante:

array< int, 5 > &fillarr( array< int, 5 > &arr ) {
    return arr; // "array" being boost::array or std::array
}

La arrayplantilla simplemente genera una structmatriz que contiene un estilo C, por lo que puede aplicar una semántica orientada a objetos y conservar la simplicidad original de la matriz.

Agua de patata
fuente
44
+1 para dar un ejemplo de cómo se puede pasar una matriz por referencia. Pero está equivocado porque no puede devolver una matriz por referencia. La sintaxis más sencilla de lograrlo es mediante el uso de un typedef: typedef int array[5]; array& foo();Pero usted ni siquiera necesita el typedef si es que quiere escribir esto: int (&foo())[5] { static int a[5] = {}; return a; }, el ejemplo de la pregunta sería: int (&foo( int (&a)[5] ))[5] { return a; }. Simple, ¿no es así?
David Rodríguez - dribeas
@David: gracias, recibí la impresión errónea del mensaje de Comeau error: function returning array is not allowedque ocurre si se omiten los parentes externos en la sintaxis no typedef. Afortunadamente, hoy revisé la regla derecha-izquierda para otra pregunta y logré construir lo correcto ... después de ver que dijiste que es posible ... antes de ver que le diste el código: vP.
Potatoswatter
1
La respuesta de chubsdad tiene la cita correcta del estándar: no puede devolver una matriz, pero puede devolver una referencia o puntero a una matriz. Las matrices no se pueden copiar (como tipo) y, como tales, no se pueden devolver, lo que implicaría una copia, y cuando esa sintaxis está presente, el compilador convertirá el argumento en un puntero.
David Rodríguez - dribeas
3
@David: Así es. Esta página se está volviendo extrañamente larga. Nunca tantas personas han escrito voluntariamente tantas funciones triviales que devuelven una matriz en un solo lugar.
Potatoswatter
@Potatoswatter Soy nuevo en cpp, ¿Puedes explicar el segundo fragmento de código en detalle? No puedo dividirlo en partes en aras de la comprensión.
KPMG
23

En C ++ 11, puede regresar std::array.

#include <array>
using namespace std;

array<int, 5> fillarr(int arr[])
{
    array<int, 5> arr2;
    for(int i=0; i<5; ++i) {
        arr2[i]=arr[i]*2;
    }
    return arr2;
}
cubuspl42
fuente
2
Citando OP:(...) you can consider the array returned arr2, totally another array (...)
cubuspl42
22

$ 8.3.5 / 8 estados-

"Las funciones no tendrán un tipo de retorno de tipo de matriz o función, aunque pueden tener un tipo de retorno de puntero de tipo o referencia a tales cosas. No habrá matrices de funciones, aunque puede haber matrices de punteros a funciones".

int (&fn1(int (&arr)[5]))[5]{     // declare fn1 as returning refernce to array
   return arr;
}

int *fn2(int arr[]){              // declare fn2 as returning pointer to array
   return arr;
}


int main(){
   int buf[5];
   fn1(buf);
   fn2(buf);
}
Chubsdad
fuente
77
Su segunda función devuelve un puntero a un int, no a una matriz.
GManNickG
de nuevo, ¿por qué devolver el tipo cuando la matriz real se actualiza dentro de la función? ¿Es una cuestión de mejores prácticas?
Dan
14

la respuesta puede depender un poco de cómo planea usar esa función. Para la respuesta más simple, decidamos que en lugar de una matriz, lo que realmente quiere es un vector. Los vectores son agradables porque el aspecto de todo el mundo es aburrido, los valores ordinarios que puede almacenar en punteros regulares. Veremos otras opciones y por qué las quiere después:

std::vector<int> fillarr( std::vector<int> arr ) {
    // do something
    return arr;
}

Esto hará exactamente lo que espera que haga. Lo bueno es questd::vector se asegura de que todo se maneje de manera limpia. La desventaja es que esto copia una gran cantidad de datos, si su matriz es grande. De hecho, copia cada elemento de la matriz dos veces. primero copia el vector para que la función pueda usarlo como parámetro. luego lo copia nuevamente para devolverlo a la persona que llama. Si puede manejar la administración del vector usted mismo, puede hacer las cosas con bastante más facilidad. (puede copiarlo por tercera vez si la persona que llama necesita almacenarlo en una variable de algún tipo para hacer más cálculos)

Parece que lo que realmente estás tratando de hacer es llenar una colección. Si no tiene un motivo específico para devolver una nueva instancia de una colección, no lo haga. podemos hacerlo así

void fillarr(std::vector<int> &  arr) {
    // modify arr
    // don't return anything
}

De esta forma, obtiene una referencia a la matriz que se pasa a la función, no una copia privada de la misma. la persona que llama puede ver cualquier cambio que realice en el parámetro. Podría devolverle una referencia si lo desea, pero esa no es una gran idea, ya que implica que está obteniendo algo diferente de lo que aprobó.

Si realmente necesita una nueva instancia de la colección, pero desea evitar tenerla en la pila (y todas las copias que conlleva), debe crear algún tipo de contrato sobre cómo se maneja esa instancia. la forma más fácil de hacerlo es usar un puntero inteligente, que mantiene la instancia referenciada mientras alguien la esté sosteniendo. Se va limpiamente si se sale del alcance. Eso se vería así.

std::auto_ptr<std::vector<int> > fillarr( const std::vector<int> & arr) {
    std::auto_ptr<std::vector<int> > myArr(new std::vector<int>);
    // do stuff with arr and *myArr
    return myArr;
}

En su mayor parte, el uso *myArrfunciona de manera idéntica al uso de un vector simple de vainilla. Este ejemplo también modifica la lista de parámetros al agregar la constpalabra clave. Ahora obtiene una referencia sin copiarla, pero no puede modificarla, por lo que la persona que llama sabe que será la misma que antes de que la función llegara a ella.

Todo esto es genial, pero la idiomática c ++ rara vez funciona con colecciones en su conjunto. Más normalmente, usará iteradores sobre esas colecciones. eso se vería más como esto

template <class Iterator>
Iterator fillarr(Iterator arrStart, Iterator arrEnd) {
    Iterator arrIter = arrStart;
    for(;arrIter <= arrEnd; arrIter++)
       ;// do something
    return arrStart;
}

Usarlo parece un poco extraño si no estás acostumbrado a ver este estilo.

vector<int> arr;
vector<int>::iterator foo = fillarr(arr.begin(), arr.end());

foo ahora 'señala' el comienzo de la modificación arr.

Lo que es realmente bueno de esto es que funciona igual de bien en vectores que en matrices C simples y muchos otros tipos de colección, por ejemplo

int arr[100];
int *foo = fillarr(arr, arr+100);

Que ahora se parece muchísimo a los ejemplos de punteros simples dados en otra parte de esta pregunta.

SingleNegationElimination
fuente
La sintaxis es incorrecta, el &símbolo debe aparecer después del tipo:void fillarr(std::vector<int> & arr)
David Rodríguez - dribeas
9

Esta:

int fillarr(int arr[])

en realidad se trata igual que:

int fillarr(int *arr)

Ahora, si realmente desea devolver una matriz, puede cambiar esa línea a

int * fillarr(int arr[]){
    // do something to arr
    return arr;
}

Realmente no está devolviendo una matriz. está devolviendo un puntero al inicio de la dirección de la matriz.

Pero recuerde que cuando pasa en la matriz, solo pasa un puntero. Entonces, cuando modifica los datos de la matriz, en realidad está modificando los datos a los que apunta el puntero. Por lo tanto, antes de pasar la matriz, debe darse cuenta de que ya tiene en el exterior el resultado modificado.

p.ej

int fillarr(int arr[]){
   array[0] = 10;
   array[1] = 5;
}

int main(int argc, char* argv[]){
   int arr[] = { 1,2,3,4,5 };

   // arr[0] == 1
   // arr[1] == 2 etc
   int result = fillarr(arr);
   // arr[0] == 10
   // arr[1] == 5    
   return 0;
}

Sugiero que desee considerar poner una longitud en su función fillarr como esta.

int * fillarr(int arr[], int length)

De esa manera, puede usar la longitud para llenar la matriz a su longitud sin importar cuál sea.

Para usarlo realmente correctamente. Haz algo como esto:

int * fillarr(int arr[], int length){
   for (int i = 0; i < length; ++i){
      // arr[i] = ? // do what you want to do here
   }
   return arr;
}

// then where you want to use it.
int arr[5];
int *arr2;

arr2 = fillarr(arr, 5);

// at this point, arr & arr2 are basically the same, just slightly
// different types.  You can cast arr to a (char*) and it'll be the same.

Si todo lo que desea hacer es establecer la matriz en algunos valores predeterminados, considere usar la función integrada de memset.

algo como: memset ((int *) & arr, 5, sizeof (int));

Aunque estoy en el tema sin embargo. Dices que estás usando C ++. Echa un vistazo al uso de vectores stl. Es probable que su código sea más robusto.

Hay muchos tutoriales. Aquí hay uno que le da una idea de cómo usarlos. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html

Mate
fuente
Usar std::copymás memset, es más seguro y más fácil. (E igual de rápido si no más rápido)
GManNickG
5

para devolver una matriz de una función, definamos esa matriz en una estructura; Entonces se ve algo como esto

struct Marks{
   int list[5];
}

Ahora creemos variables de la estructura de tipo.

typedef struct Marks marks;
marks marks_list;

Podemos pasar la matriz a una función de la siguiente manera y asignarle un valor:

void setMarks(int marks_array[]){
   for(int i=0;i<sizeof(marks_array)/sizeof(int);i++)
       marks_list.list[i]=marks_array[i];
}

También podemos devolver la matriz. Para devolver la matriz, el tipo de retorno de la función debe ser de tipo estructura, es decir, marcas. Esto se debe a que en realidad estamos pasando la estructura que contiene la matriz. Entonces el código final puede verse así.

marks getMarks(){
 return marks_list;
}
Sandeep
fuente
5

Esta es una pregunta bastante antigua, pero voy a poner mis 2 centavos, ya que hay muchas respuestas, pero ninguna muestra todos los métodos posibles de una manera clara y concisa (no estoy seguro acerca del bit conciso, ya que esto obtuvo un poco fuera de control TL; DR 😉).

Supongo que el OP quería devolver la matriz que se pasó sin copiar, ya que algunos medios de pasar esto directamente al llamador para que se pase a otra función para que el código se vea más bonito.

Sin embargo, usar una matriz como esta es dejar que se descomponga en un puntero y que el compilador la trate como una matriz. Esto puede provocar errores sutiles si pasa en una matriz como, con la función esperando que tenga 5 elementos, pero su llamador realmente pasa algún otro número.

Hay algunas maneras en que puede manejar esto mejor. Pase en unstd::vector o std::array(no estoy seguro si std::arrayexistía en 2010 cuando se hizo la pregunta). Luego puede pasar el objeto como referencia sin copiar ni mover el objeto.

std::array<int, 5>& fillarr(std::array<int, 5>& arr)
{
    // (before c++11)
    for(auto it = arr.begin(); it != arr.end(); ++it)
    { /* do stuff */ }

    // Note the following are for c++11 and higher.  They will work for all
    // the other examples below except for the stuff after the Edit.

    // (c++11 and up)
    for(auto it = std::begin(arr); it != std::end(arr); ++it)
    { /* do stuff */ }

    // range for loop (c++11 and up)
    for(auto& element : arr)
    { /* do stuff */ }

    return arr;
}

std::vector<int>& fillarr(std::vector<int>& arr)
{
    for(auto it = arr.begin(); it != arr.end(); ++it)
    { /* do stuff */ }
    return arr;
}

Sin embargo, si insiste en jugar con matrices C, utilice una plantilla que mantenga la información de cuántos elementos hay en la matriz.

template <size_t N>
int(&fillarr(int(&arr)[N]))[N]
{
    // N is easier and cleaner than specifying sizeof(arr)/sizeof(arr[0])
    for(int* it = arr; it != arr + N; ++it)
    { /* do stuff */ }
    return arr;
}

Excepto que parece feo y súper difícil de leer. Ahora uso algo para ayudar con lo que no existía en 2010, que también uso para los punteros de función:

template <typename T>
using type_t = T;

template <size_t N>
type_t<int(&)[N]> fillarr(type_t<int(&)[N]> arr)
{
    // N is easier and cleaner than specifying sizeof(arr)/sizeof(arr[0])
    for(int* it = arr; it != arr + N; ++it)
    { /* do stuff */ }
    return arr;
}

Esto mueve el tipo donde uno esperaría que fuera, haciendo que esto sea mucho más legible. Por supuesto, usar una plantilla es superfluo si no va a usar nada más que 5 elementos, por lo que puede, por supuesto, codificarlo:

type_t<int(&)[5]> fillarr(type_t<int(&)[5]> arr)
{
    // Prefer using the compiler to figure out how many elements there are
    // as it reduces the number of locations where you have to change if needed.
    for(int* it = arr; it != arr + sizeof(arr)/sizeof(arr[0]); ++it)
    { /* do stuff */ }
    return arr;
}

Como dije, mi type_t<>truco no hubiera funcionado cuando se hizo esta pregunta. Lo mejor que podría haber esperado en ese entonces era usar un tipo en una estructura:

template<typename T>
struct type
{
  typedef T type;
};

typename type<int(&)[5]>::type fillarr(typename type<int(&)[5]>::type arr)
{
    // Prefer using the compiler to figure out how many elements there are
    // as it reduces the number of locations where you have to change if needed.
    for(int* it = arr; it != arr + sizeof(arr)/sizeof(arr[0]); ++it)
    { /* do stuff */ }
    return arr;
}

Lo que comienza a verse bastante feo nuevamente, pero al menos es aún más legible, aunque typenamepuede haber sido opcional en ese momento dependiendo del compilador, lo que resulta en:

type<int(&)[5]>::type fillarr(type<int(&)[5]>::type arr)
{
    // Prefer using the compiler to figure out how many elements there are
    // as it reduces the number of locations where you have to change if needed.
    for(int* it = arr; it != arr + sizeof(arr)/sizeof(arr[0]); ++it)
    { /* do stuff */ }
    return arr;
}

Y luego, por supuesto, podría haber especificado un tipo específico, en lugar de usar mi ayudante.

typedef int(&array5)[5];

array5 fillarr(array5 arr)
{
    // Prefer using the compiler to figure out how many elements there are
    // as it reduces the number of locations where you have to change if needed.
    for(int* it = arr; it != arr + sizeof(arr)/sizeof(arr[0]); ++it)
    { /* do stuff */ }
    return arr;
}

En aquel entonces, las funciones gratuitas std::begin()ystd::end() no existían, aunque podrían haberse implementado fácilmente. Esto habría permitido iterar sobre la matriz de una manera más segura ya que tienen sentido en una matriz C, pero no en un puntero.

En cuanto al acceso a la matriz, puede pasarla a otra función que tome el mismo tipo de parámetro o crear un alias (lo que no tendría mucho sentido ya que ya tiene el original en ese ámbito). Acceder a una referencia de matriz es como acceder a la matriz original.

void other_function(type_t<int(&)[5]> x) { /* do something else */ }

void fn()
{
    int array[5];
    other_function(fillarr(array));
}

o

void fn()
{
    int array[5];
    auto& array2 = fillarr(array); // alias. But why bother.
    int forth_entry = array[4];
    int forth_entry2 = array2[4]; // same value as forth_entry
}

Para resumir, es mejor no permitir que una matriz decaiga en un puntero si tiene la intención de iterar sobre ella. Es una mala idea, ya que evita que el compilador lo proteja de dispararse en el pie y hace que su código sea más difícil de leer. Siempre intente ayudar al compilador a ayudarlo manteniendo los tipos el mayor tiempo posible a menos que tenga una muy buena razón para no hacerlo.

Editar

Ah, y para completar, puede permitir que se degrade en un puntero, pero esto desacopla la matriz de la cantidad de elementos que contiene. Esto se hace mucho en C / C ++ y generalmente se mitiga al pasar el número de elementos en la matriz. Sin embargo, el compilador no puede ayudarlo si comete un error y pasa el valor incorrecto a la cantidad de elementos.

// separate size value
int* fillarr(int* arr, size_t size)
{
    for(int* it = arr; it != arr + size; ++it)
    { /* do stuff */ }
    return arr;
}

En lugar de pasar el tamaño, puede pasar el puntero final, que apuntará a uno más allá del final de su matriz. Esto es útil ya que crea algo que está más cerca de los algoritmos estándar, que toman un puntero de inicio y fin, pero lo que devuelve ahora es solo algo que debe recordar.

// separate end pointer
int* fillarr(int* arr, int* end)
{
    for(int* it = arr; it != end; ++it)
    { /* do stuff */ }
    return arr;
}

Alternativamente, puede documentar que esta función solo tomará 5 elementos y esperar que el usuario de su función no haga nada estúpido.

// I document that this function will ONLY take 5 elements and 
// return the same array of 5 elements.  If you pass in anything
// else, may nazal demons exit thine nose!
int* fillarr(int* arr)
{
    for(int* it = arr; it != arr + 5; ++it)
    { /* do stuff */ }
    return arr;
}

Tenga en cuenta que el valor de retorno ha perdido su tipo original y se degrada a un puntero. Debido a esto, ahora está solo para asegurarse de que no va a sobrepasar la matriz.

Podrías pasar un std::pair<int*, int*>, que puedes usar para comenzar y terminar y pasarlo, pero luego deja de parecer una matriz.

std::pair<int*, int*> fillarr(std::pair<int*, int*> arr)
{
    for(int* it = arr.first; it != arr.second; ++it)
    { /* do stuff */ }
    return arr; // if you change arr, then return the original arr value.
}

void fn()
{
    int array[5];
    auto array2 = fillarr(std::make_pair(&array[0], &array[5]));

    // Can be done, but you have the original array in scope, so why bother.
    int fourth_element = array2.first[4];
}

o

void other_function(std::pair<int*, int*> array)
{
    // Can be done, but you have the original array in scope, so why bother.
    int fourth_element = array2.first[4];
}

void fn()
{
    int array[5];
    other_function(fillarr(std::make_pair(&array[0], &array[5])));
}

Curiosamente, esto es muy similar a cómo std::initializer_listfunciona (c ++ 11), pero no funcionan en este contexto.

Adrian
fuente
3

La forma más simple de hacer esto es devolverlo por referencia, incluso si no escribe el símbolo '&', se devuelve automáticamente por referencia

     void fillarr(int arr[5])
  {
       for(...);

  }
nada
fuente
2
int *fillarr(int arr[])

Todavía puedes usar el resultado como

int *returned_array = fillarr(some_other_array);
if(returned_array[0] == 3)
    do_important_cool_stuff();
Daniel
fuente
No creo que el 'int [] fillarr ...' sea legal. El 'int * fillarr' es lo que usaría debido a la equivalencia de puntero de matriz.
Seand
1

Como se mencionó anteriormente, las rutas son correctas. Pero creo que si solo devolvemos una variable de matriz local de una función, a veces devuelve valores basura como sus elementos.

para evitar tener que crear la matriz dinámicamente y continuar. Que es algo como esto.

int* func()
{
  int* Arr = new int[100];
  return Arr;
}

int main()
{
  int* ArrResult = func();
  cout << ArrResult[0] << " " << ArrResult[1] << endl;
  return 0;
} 



Shehanmark
fuente
0
template<typename T, size_t N>
using ARR_REF = T (&)[N];

template <typename T, size_t N>
ARR_REF<T,N> ArraySizeHelper(ARR_REF<T,N> arr);

#define arraysize(arr) sizeof(ArraySizeHelper(arr))
Nozama
fuente
0

Fuente: https://www.tutorialspoint.com/cplusplus/cpp_return_arrays_from_functions.htm

C ++ no permite devolver una matriz completa como argumento para una función. Sin embargo, puede devolver un puntero a una matriz especificando el nombre de la matriz sin un índice.

  1. Si desea devolver una matriz de dimensión única de una función, deberá declarar una función que devuelva un puntero como en el siguiente ejemplo:
int * myFunction()    {
   .
   .
   .
}
  1. C ++ no recomienda devolver la dirección de una variable local al exterior de la función, por lo que tendría que definir la variable local como variable estática.

Aplicando estas reglas a la pregunta actual, podemos escribir el programa de la siguiente manera:

# include <iostream>

using namespace std;

int * fillarr( );


int main ()
{

   int *p;

   p = fillarr();

   for ( int i = 0; i < 5; i++ )
       cout << "p[" << i << "] : "<< *(p + i) << endl;

    return 0;
}


int * fillarr( )
{
    static int  arr[5];

    for (int i = 0; i < 5; ++i)
        arr[i] = i;

    return arr;
 }

La salida será:

p[0]=0
p[1]=1
p[2]=2
p[3]=3
p[4]=4
MAQ
fuente
0

y que hay con:

int (*func())
{
    int *f = new int[10] {1,2,3};

    return f;
}

int fa[10] = { 0 };
auto func2() -> int (*) [10]
{
    return &fa;
}
Alexandr
fuente
0

En realidad, cuando pasa una matriz dentro de una función, el puntero a la matriz original se pasa en el parámetro de la función y, por lo tanto, los cambios realizados en la matriz dentro de esa función se realizan realmente en la matriz original.

#include <iostream>

using namespace std;

int* func(int ar[])
{
    for(int i=0;i<100;i++) 
        ar[i]=i;
    int *ptr=ar;
    return ptr;
}


int main() {
    int *p;
    int y[100]={0};    
    p=func(y);

    for(int i=0;i<100;i++) 
        cout<<i<<" : "<<y[i]<<'\n';
}

Ejecútalo y verás los cambios

Abhishek gaur
fuente
1
Utilice una redacción adecuada en inglés (en lugar de usted) y omita frases vacías como "amigo".
hola
Además: "entonces en realidad se pasa como referencia" está mal. La variable en ysí se pasa como una copia de sí misma, pero debido a que es un puntero, operará directamente en la matriz. Por favor edite su respuesta.
hola
stackoverflow.com/questions/5573310/… TL; DR "Por lo tanto, las dos formas son idénticas".
hellow
Sí, técnicamente es una matriz, tiene razón, pero lo que se copia es un puntero a la matriz, no la matriz en sí.
hellow
0

Aquí hay un ejemplo completo de este tipo de problema para resolver

#include <bits/stdc++.h>
using namespace std;
int* solve(int brr[],int n)
{
sort(brr,brr+n);
return brr;
}

int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
    cin>>arr[i];
}
int *a=solve(arr,n);
for(int i=0;i<n;i++)
{
    cout<<a[i]<<endl;
}

return 0;
}
Shaonsani
fuente
-2

Simplemente defina un tipo [] como valor de retorno, como:

        private string[] functionReturnValueArray(string one, string two)
    {

        string[] x = {one, two};


        x[0] = "a";
        x[1] = "b";

        return x;
    }

. . . Llamada de función:

string[] y;
y = functionReturnValueArray(stringOne, stringTwo)
Ricardo Fercher
fuente
55
Esto no es C ++
Adrian