Retornar matriz em uma função

212

Eu tenho uma matriz int arr[5]que é passada para uma função fillarr(int arr[]):

int fillarr(int arr[])
{
    for(...);
    return arr;
}
  1. Como posso retornar essa matriz?
  2. Como vou usá-lo, digamos que retornei um ponteiro, como vou acessá-lo?
Ismail Marmoush
fonte
46
estritamente falando neste contexto, você não precisa retornar a matriz, uma vez que a matriz é passada por referência; portanto, quaisquer alterações nos elementos dentro de 'arr' serão vistas fora da função.
BuggerMe
12
retornar o array é conveniente para encadear funções.
seand
5
Desde que você não cometa o erro de criar uma matriz na pilha e retornar um ponteiro para ela.
detly 13/08/10
2
@ismail: não pode retornar uma nova matriz, a menos que essa matriz tenha sido alocada dinamicamente. E se for esse o caso, use std::vector.
GManNickG
4
@ BuggerMe: matrizes não são passadas por referência (a menos que você solicite com uma sintaxe muito mais engraçada); no código, a matriz decai em um ponteiro para o primeiro elemento e que é passado para a função. A 5assinatura na função é descartada pelo compilador.
David Rodríguez - dribeas 13/08/10

Respostas:

204

Nesse caso, sua variável de matriz arrtambém pode ser tratada como um ponteiro para o início do bloco da matriz na memória, por uma conversão implícita. Esta sintaxe que você está usando:

int fillarr(int arr[])

É uma espécie de açúcar sintático. Você poderia realmente substituí-lo por isso e ainda funcionaria:

int fillarr(int* arr)

Portanto, no mesmo sentido, o que você deseja retornar da sua função é na verdade um ponteiro para o primeiro elemento da matriz:

int* fillarr(int arr[])

E você ainda poderá usá-lo exatamente como faria em um array normal:

int main()
{
  int y[10];
  int *a = fillarr(y);
  cout << a[0] << endl;
}
Brent escreve código
fonte
45
Para esclarecer, essa "declaração clássica de C ++" é falsa; matrizes não são ponteiros.
GManNickG
25
lembre-se a uma [i] == * (a + i) regra
seand
8
@Brent Nash, não. uma matriz é uma matriz. Um ponteiro para o início da matriz é um ponteiro. Acontece que o compilador tem um pouco de açúcar sintático que faz a tradução para você em algumas situações. arraye &arraysão intercambiáveis ​​em muitos casos.
Carl Norum
20
@Brent: Não. Uma matriz é do seu próprio tipo, não é um tipo especial de ponteiro. O tipo de aem int a[10]é int[10]. O que você pode dizer é que as matrizes "deterioram" em ponteiros para o primeiro elemento. (Esta é uma conversão implícita de matriz em ponteiro.) Então sua resposta seguirá as linhas que a minha faz. Se você editar sua resposta para diferenciar matrizes, conversão de matriz para ponteiro e ponteiros, excluirei minha resposta, pois elas teriam as mesmas informações principais e você foi o primeiro.
GManNickG
8
@seand lembrar a a [i] == * (a + sizeof (a) * i) regra
Amir
114

As funções C ++ não podem retornar matrizes no estilo C por valor. O mais próximo é retornar um ponteiro. Além disso, um tipo de matriz na lista de argumentos é simplesmente convertido em um ponteiro.

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

Você pode aprimorá-lo usando referências de matriz para o argumento e retorno, o que impede a deterioração:

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

Com o Boost ou o C ++ 11, a passagem por referência é apenas opcional e a sintaxe é menos preocupante:

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

O arraymodelo simplesmente gera um que structcontém uma matriz no estilo C, para que você possa aplicar a semântica orientada a objetos e ainda manter a simplicidade original da matriz.

Potatoswatter
fonte
4
+1 para dar um exemplo de como uma matriz pode ser transmitida por referência. Mas você está errado, pois não pode retornar uma matriz por referência. A sintaxe mais simples de conseguir isso é usando um typedef: typedef int array[5]; array& foo();Mas você não precisa mesmo do typedef se o cuidado de escrever isto: int (&foo())[5] { static int a[5] = {}; return a; }o exemplo na pergunta seria: int (&foo( int (&a)[5] ))[5] { return a; }. Simples, não é?
David Rodríguez - dribeas 13/08
@ David: obrigado, eu recebi a impressão errada da mensagem do Comeau error: function returning array is not allowedque ocorre se você deixar de fora os parâmetros externos na sintaxe não digitada. Felizmente, hoje revi a regra da direita para a esquerda para outra pergunta e consegui construir a coisa certa ... depois de ver você dizer que é possível ... antes de ver que você deu o código: vP.
Potatoswatter 13/08/10
1
A resposta de chubsdad tem a citação correta do padrão: você não pode retornar uma matriz, mas pode retornar uma referência ou ponteiro para uma matriz. As matrizes não são copiáveis ​​(como um tipo) e, como tal, não podem ser retornadas - o que implicaria uma cópia - e quando essa sintaxe estiver presente, o compilador converterá o argumento em um ponteiro.
David Rodríguez - dribeas 13/08
3
@ David: O mesmo acontece. Esta página está ficando estranhamente longa. Nunca tantas pessoas escreveram voluntariamente tantas funções triviais retornando uma matriz em um só lugar.
Potatoswatter 13/08/10
@Potatoswatter Eu sou novo no cpp. Você pode explicar o segundo trecho de código em detalhes? Não sou capaz de dividi-lo em partes por uma questão de compreensão.
KPMG
23

No C ++ 11, você pode retornar 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
fonte
2
Citando OP:(...) you can consider the array returned arr2, totally another array (...)
cubuspl42
22

$ 8.3.5 / 8 estados-

"As funções não devem ter um tipo de retorno de matriz ou função de tipo, embora possam ter um tipo de retorno de ponteiro de tipo ou referência a essas coisas. Não deve haver matrizes de funções, embora possa haver matrizes de ponteiros para funções".

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
fonte
7
Sua segunda função retorna um ponteiro para um int, não um array.
GManNickG
novamente, por que retornar o tipo quando a matriz real é atualizada dentro da função? É uma questão de boas práticas?
Dan
14

a resposta pode depender um pouco de como você planeja usar essa função. Para a resposta mais simples, vamos decidir que, em vez de uma matriz, o que você realmente deseja é um vetor. Os vetores são bons porque a aparência de todo o mundo é como valores comuns e chatos que você pode armazenar em indicadores regulares. Veremos outras opções e por que você as deseja posteriormente:

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

Isso fará exatamente o que você espera. A vantagem é que std::vectorse certifica de que tudo seja tratado de maneira limpa. A desvantagem é que isso copia uma quantidade muito grande de dados, se sua matriz for grande. De fato, ele copia todos os elementos da matriz duas vezes. primeiro copia o vetor para que a função possa usá-lo como parâmetro. depois o copia novamente para devolvê-lo ao chamador. Se você conseguir gerenciar o vetor você mesmo, poderá fazer as coisas com mais facilidade. (ele pode ser copiado uma terceira vez se o chamador precisar armazená-lo em uma variável de algum tipo para fazer mais cálculos)

Parece que o que você realmente está tentando fazer é preencher uma coleção. se você não tiver um motivo específico para retornar uma nova instância de uma coleção, não o faça. podemos fazer assim

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

dessa forma, você obtém uma referência à matriz passada para a função, não uma cópia particular dela. todas as alterações feitas no parâmetro são vistas pelo chamador. Você pode retornar uma referência a ela, se quiser, mas isso não é realmente uma ótima idéia, pois implica que você está recebendo algo diferente do que passou.

Se você realmente precisa de uma nova instância da coleção, mas deseja evitar tê-la na pilha (e em todas as cópias que isso implica), é necessário criar algum tipo de contrato para o tratamento dessa instância. a maneira mais fácil de fazer isso é usar um ponteiro inteligente, que mantém a instância referenciada por mais tempo que alguém a esteja segurando. Ele desaparece de forma limpa se sair do escopo. Isso seria assim.

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;
}

Na maioria das vezes, o uso *myArrfunciona de forma idêntica ao uso de um vetor de baunilha comum. Este exemplo também modifica a lista de parâmetros adicionando a constpalavra - chave. Agora você obtém uma referência sem copiá-la, mas não pode modificá-la, portanto o chamador sabe que será o mesmo de antes da função.

Tudo isso é ótimo, mas o c ++ idiomático raramente funciona com coleções como um todo. Mais normalmente, você usará iteradores sobre essas coleções. que seria algo mais parecido com isto

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

Usá-lo parece um pouco estranho se você não está acostumado a ver esse estilo.

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

foo agora 'aponta para' o início do modificado arr.

O que é realmente bom nisso é que ele funciona igualmente bem em vetores, como em matrizes C simples e em muitos outros tipos de coleção, por exemplo

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

Que agora se parece muito com os exemplos simples de ponteiros dados em outras partes desta questão.

SingleNegationElimination
fonte
A sintaxe está incorreta, o &símbolo deve aparecer após o tipo:void fillarr(std::vector<int> & arr)
David Rodríguez - dribeas 13/08
9

Este:

int fillarr(int arr[])

é realmente tratado da mesma forma que:

int fillarr(int *arr)

Agora, se você realmente deseja retornar uma matriz, pode alterar essa linha para

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

Não está realmente retornando uma matriz. você está retornando um ponteiro para o início do endereço da matriz.

Mas lembre-se de que quando você passa na matriz, está passando apenas um ponteiro. Portanto, quando você modifica os dados da matriz, na verdade está modificando os dados para os quais o ponteiro está apontando. Portanto, antes de passar na matriz, você deve perceber que já possui fora o resultado modificado.

por exemplo

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;
}

Sugiro que você considere colocar um comprimento em sua função fillarr dessa maneira.

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

Dessa forma, você pode usar o comprimento para preencher a matriz com seu comprimento, não importa qual seja.

Para realmente usá-lo corretamente. Faça algo parecido com isto:

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.

Se tudo o que você deseja fazer é definir a matriz com alguns valores padrão, considere usar a função memset integrada.

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

Enquanto eu estou no assunto, no entanto. Você diz que está usando C ++. Dê uma olhada no uso de vetores stl. É provável que seu código seja mais robusto.

Existem muitos tutoriais. Aqui está um que lhe dá uma idéia de como usá-los. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html

Matt
fonte
Use std::copymais memset, é mais seguro e fácil. (. E tão rápido se não mais rápido)
GManNickG
5

para retornar uma matriz de uma função, vamos definir essa matriz em uma estrutura; Então parece algo assim

struct Marks{
   int list[5];
}

Agora vamos criar variáveis ​​da estrutura de tipos.

typedef struct Marks marks;
marks marks_list;

Podemos passar a matriz para uma função da seguinte maneira e atribuir valor a ela:

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

Também podemos retornar a matriz. Para retornar a matriz, o tipo de retorno da função deve ser do tipo estrutura, ou seja, marcas. Isso ocorre porque, na realidade, estamos passando a estrutura que contém a matriz. Portanto, o código final pode ficar assim.

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

Essa é uma pergunta bastante antiga, mas vou colocar meus 2 centavos, pois há muitas respostas, mas nenhuma mostrando todos os métodos possíveis de maneira clara e concisa (não tenho certeza do que é conciso, pois isso tem uma pouco fora de mão TL; DR 😉).

Estou assumindo que o OP queria retornar a matriz que foi passada sem copiar, como forma de passar isso diretamente para o chamador a ser passado para outra função para tornar o código mais bonito.

No entanto, usar uma matriz como essa é permitir que ela se decomponha em um ponteiro e faça com que o compilador a trate como uma matriz. Isso pode resultar em erros sutis se você passar em uma matriz como, com a função esperando que ela tenha 5 elementos, mas o chamador realmente passa em algum outro número.

Existem algumas maneiras de lidar melhor com isso. Passe um std::vectorou std::array(não tenho certeza se std::arrayexistia em 2010 quando a pergunta foi feita). Você pode então passar o objeto como uma referência sem copiar / mover o 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;
}

No entanto, se você insistir em jogar com matrizes C, use um modelo que manterá as informações de quantos itens na 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;
}

Exceto que parece feio e super difícil de ler. Agora uso algo para ajudar com o que não existia em 2010, que também uso para ponteiros de função:

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;
}

Isso move o tipo onde se esperaria, tornando isso muito mais legível. Obviamente, o uso de um modelo é supérfluo se você não usar nada além de cinco elementos, portanto é possível codificá-lo:

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 eu disse, meu type_t<>truque não teria funcionado no momento em que essa pergunta foi feita. O melhor que você poderia esperar naquela época era usar um tipo em uma estrutura:

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;
}

O que começa a parecer muito feio novamente, mas pelo menos ainda é mais legível, embora typenamepossa ter sido opcional na época, dependendo do compilador, resultando em:

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;
}

E então é claro que você poderia ter especificado um tipo específico, em vez de usar meu ajudante.

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;
}

Naquela época, as funções livres std::begin()e std::end()não existiam, embora poderiam ter sido facilmente implementadas. Isso permitiria iterar sobre a matriz de uma maneira mais segura, pois eles fazem sentido em uma matriz C, mas não em um ponteiro.

Quanto ao acesso ao array, você pode passá-lo para outra função que usa o mesmo tipo de parâmetro ou criar um alias para ele (o que não faria muito sentido, pois você já tem o original nesse escopo). Acessar uma referência de matriz é como acessar a matriz original.

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

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

ou

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, é melhor não permitir que uma matriz decaia em um ponteiro se você pretende iterar sobre ele. É apenas uma má idéia, pois impede o compilador de protegê-lo de dar um tiro no pé e torna seu código mais difícil de ler. Sempre tente ajudar o compilador, mantendo os tipos o maior tempo possível, a menos que você tenha um bom motivo para não fazê-lo.

Editar

Ah, e para garantir a integridade, você pode degradar para um ponteiro, mas isso desacopla a matriz do número de elementos que ela contém. Isso é feito muito em C / C ++ e geralmente é atenuado passando o número de elementos na matriz. No entanto, o compilador não pode ajudá-lo se você cometer um erro e passar o valor errado para o número de elementos.

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

Em vez de passar o tamanho, você pode passar o ponteiro final, que apontará para um após o final da sua matriz. Isso é útil, pois contribui para algo mais próximo dos algoritmos std, que levam um ponteiro de início e fim, mas o que você retorna agora é apenas algo que você deve lembrar.

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

Como alternativa, você pode documentar que essa função terá apenas 5 elementos e espere que o usuário da sua função não faça 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;
}

Observe que o valor de retorno perdeu seu tipo original e é degradado em um ponteiro. Por causa disso, agora você está por conta própria para garantir que não exceda a matriz.

Você pode passar um std::pair<int*, int*>, que você pode usar para começar, terminar e passar por aí, mas depois ele realmente para de parecer uma 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];
}

ou

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])));
}

Engraçado o bastante, isso é muito parecido com o std::initializer_listtrabalho (c ++ 11), mas eles não funcionam nesse contexto.

Adrian
fonte
3

a maneira mais simples de fazer isso é retorná-lo por referência, mesmo que você não escreva o símbolo '&', ele será retornado automaticamente por referência

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

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

Você ainda pode usar o resultado como

int *returned_array = fillarr(some_other_array);
if(returned_array[0] == 3)
    do_important_cool_stuff();
Daniel
fonte
Eu não acho que o 'int [] fillarr ...' seja legal. O 'int * fillarr' é o que você usaria devido à equivalência de ponteiro de matriz.
seand
1

Como os caminhos mencionados acima estão corretos. Mas acho que, se retornarmos uma variável de matriz local de uma função, algumas vezes ela retornará valores de lixo como seus elementos.

para evitar que eu tivesse que criar a matriz dinamicamente e continuar. O que é algo assim.

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

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



Shehanmark
fonte
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
fonte
0

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

C ++ não permite retornar uma matriz inteira como argumento para uma função. No entanto, você pode retornar um ponteiro para uma matriz especificando o nome da matriz sem um índice.

  1. Se você deseja retornar uma matriz de dimensão única de uma função, teria que declarar uma função retornando um ponteiro, como no exemplo a seguir:
int * myFunction()    {
   .
   .
   .
}
  1. O C ++ não recomenda retornar o endereço de uma variável local para fora da função; portanto, você deve definir a variável local como variável estática.

Aplicando essas regras na pergunta atual, podemos escrever o programa da seguinte maneira:

# 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;
 }

A saída será:

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

e sobre:

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

    return f;
}

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

Na verdade, quando você passa uma matriz dentro de uma função, o ponteiro para a matriz original é passado no parâmetro function e, portanto, as alterações feitas na matriz dentro dessa função são realmente feitas na 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';
}

Execute-o e você verá as alterações

Abhishek gaur
fonte
1
Por favor, use o texto em inglês adequado (em vez de você) e omita frases vazias como "amigo".
hellow
Além disso: "então, na verdade, é passado como referência" está errado. A variável em ysi é passada como uma cópia de si mesma, mas como é um ponteiro, você operará diretamente na matriz. Edite sua resposta.
hellow
stackoverflow.com/questions/5573310/… TL; DR "Portanto, os dois formulários são idênticos."
hellow
Sim, tecnicamente é uma matriz, você está certo, mas o que é copiado é um ponteiro para a matriz, não a matriz em si.
hellow
0

Aqui está um exemplo completo deste 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
fonte
-2

Apenas defina um 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;
    }

. . . chamada de função:

string[] y;
y = functionReturnValueArray(stringOne, stringTwo)
Ricardo Fercher
fonte
5
Isso não é C ++
Adrian