Restituisce l'array in una funzione


212

Ho un array int arr[5]che viene passato a una funzione fillarr(int arr[]):

int fillarr(int arr[])
{
    for(...);
    return arr;
}
  1. Come posso restituire quell'array?
  2. Come lo userò, diciamo che ho restituito un puntatore come posso accedervi?

46
in senso stretto in questo contesto non è necessario restituire l'array poiché l'array viene passato per riferimento, quindi eventuali modifiche agli elementi all'interno di 'arr' verranno visualizzate all'esterno della funzione.
BuggerMe

12
la restituzione dell'array è utile per le funzioni di concatenamento.
seand

5
Finché non stai commettendo l'errore di creare un array nello stack e restituire un puntatore ad esso.
Detly

2
@ismail: non può restituire un nuovo array, a meno che tale array non sia stato allocato dinamicamente. E se è così, usa std::vector.
GManNickG

4
@BuggerMe: le matrici non vengono passate per riferimento (a meno che non venga richiesto con una sintassi molto più divertente), nel codice l'array decade in un puntatore al primo elemento e viene passato alla funzione. La 5firma nella funzione viene scartata dal compilatore.
David Rodríguez - dribeas,

Risposte:


204

In questo caso, la variabile dell'array arrpuò effettivamente essere trattata come un puntatore all'inizio del blocco dell'array in memoria, mediante una conversione implicita. Questa sintassi che stai utilizzando:

int fillarr(int arr[])

È una specie di zucchero sintattico. Potresti davvero sostituirlo con questo e funzionerebbe ancora:

int fillarr(int* arr)

Quindi, nello stesso senso, ciò che vuoi restituire dalla tua funzione è in realtà un puntatore al primo elemento dell'array:

int* fillarr(int arr[])

E sarai ancora in grado di usarlo come faresti con un normale array:

int main()
{
  int y[10];
  int *a = fillarr(y);
  cout << a[0] << endl;
}

45
Per chiarire, quella "classica istruzione C ++" è falsa; le matrici non sono puntatori.
GManNickG,

25
ricorda la regola a [i] == * (a + i)
seand

8
@Brent Nash, no. un array è un array. Un puntatore all'inizio dell'array è un puntatore. Accade solo che il compilatore abbia dello zucchero sintattico che fa la traduzione per te in alcune situazioni. arraye &arraysono intercambiabili in molti casi.
Carl Norum,

21
@Brent: No. Un array è del proprio tipo, non è un tipo speciale di puntatore. Il tipo di ain int a[10]è int[10]. Quello che puoi dire è che gli array "decadono" in puntatori al loro primo elemento. (Questa è una conversione implicita da array a puntatore.) Quindi la tua risposta andrebbe seguendo le linee della mia. Se modifichi la tua risposta per distinguere tra matrici, conversione da array a puntatore e puntatori, eliminerò la mia risposta poiché avrebbero le stesse informazioni di base e tu eri il primo.
GManNickG,

8
@seand ricorda la regola a [i] == * (a + sizeof (a) * i)
Amir

114

Le funzioni C ++ non possono restituire array in stile C per valore. La cosa più vicina è restituire un puntatore. Inoltre, un tipo di array nell'elenco degli argomenti viene semplicemente convertito in un puntatore.

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

Puoi migliorarlo usando un array di riferimenti per l'argomento e return, che impedisce il decadimento:

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

Con Boost o C ++ 11, il pass-by-reference è solo facoltativo e la sintassi è meno strabiliante:

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

Il arraymodello genera semplicemente un structarray contenente uno stile C, in modo da poter applicare la semantica orientata agli oggetti mantenendo la semplicità originale dell'array.


4
+1 per un esempio di come un array può essere passato per riferimento. Ma ti sbagli nel non poter restituire un array per riferimento. La sintassi più semplice per raggiungerlo è quello di utilizzare un typedef: typedef int array[5]; array& foo();Ma non hai nemmeno bisogno del typedef se si cura di scrivere questo: int (&foo())[5] { static int a[5] = {}; return a; }l'esempio nella domanda sarebbe: int (&foo( int (&a)[5] ))[5] { return a; }. Semplice, no?
David Rodríguez - dribeas,

@David: grazie, ho ricevuto la misimpression dal messaggio Comeau error: function returning array is not allowedche si verifica se si omettono le parentesi esterne nella sintassi non typedef. Fortunatamente, oggi ho rivisto la regola di destra per un'altra domanda e sono riuscito a costruire la cosa giusta ... dopo averti visto dire che è possibile ... prima di vedere che hai dato il codice: vP.
Potatoswatter,

1
La risposta di chubsdad ha la citazione corretta dallo standard: non è possibile restituire un array, ma è possibile restituire un riferimento o un puntatore a un array. Le matrici non sono copiabili (come tipo) e come tali non possono essere restituite - il che implicherebbe una copia - e quando è presente tale sintassi il compilatore convertirà l'argomento in un puntatore.
David Rodríguez - dribeas,

3
@ David: Così fa. Questa pagina sta diventando stranamente lunga. Mai così tante persone hanno volontariamente scritto così tante funzioni banali che restituiscono un array in un unico posto.
Potatoswatter,

@Potatoswatter Sono nuovo di CPP, puoi spiegare in dettaglio il 2 ° frammento di codice? Non sono in grado di dividerlo in parti per motivi di comprensione.
KPMG,

23

In C ++ 11, puoi tornare 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;
}

2
Citando OP:(...) you can consider the array returned arr2, totally another array (...)
cubuspl42

22

$ 8.3.5 / 8 afferma-

"Le funzioni non devono avere un tipo di ritorno di tipo array o funzione, sebbene possano avere un tipo di ritorno di tipo puntatore o riferimento a tali cose. Non devono esserci matrici di funzioni, sebbene possano esserci matrici di puntatori a funzioni."

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

7
La seconda funzione restituisce un puntatore a un int, non a un array.
GManNickG,

di nuovo, perché restituire il tipo quando l'array attuale viene aggiornato all'interno della funzione? È una questione di buone pratiche?
Dan,

14

la risposta potrebbe dipendere un po 'da come intendi utilizzare quella funzione. Per la risposta più semplice, decidiamo che invece di un array, quello che vuoi davvero è un vettore. I vettori sono belli perché l'aspetto di tutto il mondo come noioso, valori ordinari che è possibile memorizzare in puntatori regolari. Vedremo altre opzioni e perché le desideri in seguito:

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

Questo farà esattamente quello che ti aspetti che faccia. Il lato positivo è che std::vectorsi occupa di assicurarsi che tutto sia gestito in modo pulito. il rovescio della medaglia è che questo copia una grande quantità di dati, se l'array è grande. Infatti, copia due volte ogni elemento dell'array. prima copia il vettore in modo che la funzione possa usarlo come parametro. quindi lo copia di nuovo per restituirlo al chiamante. Se riesci a gestire da solo la gestione del vettore, puoi fare le cose un po 'più facilmente. (potrebbe copiarlo una terza volta se il chiamante deve memorizzarlo in una variabile di qualche tipo per fare più calcoli)

Sembra che quello che stai davvero cercando di fare sia solo popolare una raccolta. se non hai un motivo specifico per restituire una nuova istanza di una raccolta, allora non farlo. possiamo farlo in questo modo

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

in questo modo si ottiene un riferimento all'array passato alla funzione, non una sua copia privata. eventuali modifiche apportate al parametro vengono visualizzate dal chiamante. Potresti restituire un riferimento ad esso se vuoi, ma non è davvero una grande idea, dal momento che in qualche modo implica che stai ottenendo qualcosa di diverso da quello che hai passato.

Se hai davvero bisogno di una nuova istanza della raccolta, ma vuoi evitare di averla in pila (e tutta la copia che comporta), devi creare un qualche tipo di contratto per come viene gestita quell'istanza. il modo più semplice per farlo è utilizzare un puntatore intelligente, che mantiene l'istanza a cui fa riferimento fintanto che chiunque si tiene su di essa. Se non va oltre, scompare in modo pulito. Sarebbe così.

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

Per la maggior parte, l'utilizzo *myArrfunziona in modo identico all'utilizzo di un semplice vettore vaniglia. Questo esempio modifica anche l'elenco dei parametri aggiungendo la constparola chiave. Ora ottieni un riferimento senza copiarlo, ma non puoi modificarlo, quindi il chiamante sa che sarà lo stesso di prima che la funzione ci arrivasse.

Tutto ciò è perfetto, ma il c ++ idiomatico raramente funziona con le raccolte nel loro insieme. Più normalmente, userete iteratori su quelle raccolte. sarebbe qualcosa di più simile a questo

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

Usarlo sembra un po 'strano se non sei abituato a vedere questo stile.

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

foo ora "indica" l'inizio della modifica arr.

La cosa davvero bella di questo è che funziona ugualmente bene sul vettore come sulle normali matrici C e su molti altri tipi di raccolta, ad esempio

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

Che ora assomiglia moltissimo ai semplici esempi di puntatori forniti altrove in questa domanda.


La sintassi è sbagliata, il &simbolo deve apparire dopo il tipo:void fillarr(std::vector<int> & arr)
David Rodríguez - dribeas

9

Questo:

int fillarr(int arr[])

viene effettivamente trattato come:

int fillarr(int *arr)

Ora, se vuoi davvero restituire un array, puoi cambiare quella linea in

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

Non sta davvero restituendo un array. stai restituendo un puntatore all'inizio dell'indirizzo dell'array.

Ma ricorda che quando passi nell'array, stai solo passando un puntatore. Quindi, quando modifichi i dati dell'array, stai effettivamente modificando i dati a cui punta il puntatore. Pertanto, prima di passare nell'array, è necessario rendersi conto di avere già all'esterno il risultato modificato.

per esempio

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

Ti suggerisco di prendere in considerazione l'idea di inserire una lunghezza nella tua funzione fillarr in questo modo.

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

In questo modo è possibile utilizzare la lunghezza per riempire l'array fino alla sua lunghezza, qualunque essa sia.

Per usarlo correttamente. Fai qualcosa del genere:

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 tutto ciò che si desidera fare è impostare l'array su alcuni valori predefiniti, prendere in considerazione l'utilizzo della funzione memset integrata.

qualcosa come: memset ((int *) & arr, 5, sizeof (int));

Mentre sono sull'argomento però. Dici che stai usando C ++. Dai un'occhiata all'utilizzo dei vettori stl. È probabile che il tuo codice sia più robusto.

Ci sono molti tutorial. Eccone uno che ti dà un'idea di come usarli. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html


Usalo std::copysopra memset, è più sicuro e più facile. (E altrettanto veloce se non più veloce.)
GManNickG

5

per restituire un array da una funzione, definiamo tale array in una struttura; Quindi sembra qualcosa del genere

struct Marks{
   int list[5];
}

Ora creiamo variabili della struttura dei tipi.

typedef struct Marks marks;
marks marks_list;

Possiamo passare l'array a una funzione nel modo seguente e assegnargli un valore:

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

Possiamo anche restituire l'array. Per restituire l'array, il tipo restituito della funzione deve essere di tipo struttura, ad esempio segni. Questo perché in realtà stiamo passando la struttura che contiene l'array. Quindi il codice finale potrebbe apparire così.

marks getMarks(){
 return marks_list;
}

5

Questa è una domanda abbastanza vecchia, ma inserirò i miei 2 centesimi poiché ci sono molte risposte, ma nessuna mostra tutti i metodi possibili in modo chiaro e conciso (non sono sicuro del bit conciso, poiché questo ha ottenuto un bit fuori mano. TL; DR 😉).

Suppongo che l'OP abbia voluto restituire l'array che è stato passato senza copiare come mezzo per passare direttamente questo al chiamante per essere passato a un'altra funzione per rendere il codice più carino.

Tuttavia, usare un array come questo significa lasciarlo decadere in un puntatore e fare in modo che il compilatore lo tratti come un array. Ciò può comportare bug sottili se si passa in un array come, con la funzione che prevede che avrà 5 elementi, ma il chiamante passa effettivamente in qualche altro numero.

Ci sono alcuni modi per gestirlo meglio. Passa a std::vectoro std::array(non sono sicuro se std::arrayesistesse nel 2010 quando è stata posta la domanda). È quindi possibile passare l'oggetto come riferimento senza copiare / spostare l'oggetto.

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

Tuttavia, se si insiste nel giocare con le matrici C, utilizzare un modello che consenta di conservare il numero di elementi nell'array.

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

Tranne che sembra brutto e super difficile da leggere. Ora uso qualcosa per aiutare con ciò che non esisteva nel 2010, che uso anche per i puntatori a funzione:

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

Questo sposta il tipo in cui ci si aspetterebbe che sia, rendendolo molto più leggibile. Ovviamente, l'uso di un modello è superfluo se non hai intenzione di usare nient'altro che 5 elementi, quindi puoi ovviamente codificarlo con hard disk:

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

Come ho detto, il mio type_t<>trucco non avrebbe funzionato al momento in cui è stata posta questa domanda. Il meglio che avresti potuto sperare allora era usare un tipo in una struttura:

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

Che inizia a sembrare di nuovo piuttosto brutto, ma almeno è ancora più leggibile, anche se typenamepotrebbe essere stato facoltativo allora a seconda del compilatore, risultando in:

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 poi ovviamente avresti potuto specificare un tipo specifico, piuttosto che usare il mio aiuto.

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

Allora, le funzioni libere std::begin()e std::end()non esistevano, anche se avrebbero potuto essere facilmente implementate. Ciò avrebbe permesso di scorrere sull'array in un modo più sicuro poiché hanno senso su un array C, ma non su un puntatore.

Per quanto riguarda l'accesso all'array, è possibile passarlo a un'altra funzione che accetta lo stesso tipo di parametro o creare un alias (che non avrebbe molto senso in quanto l'originale è già in quell'ambito). Accedere a un riferimento di array è come accedere all'array originale.

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
}

Per riassumere, è meglio non consentire il decadimento di un array in un puntatore se si intende iterare su di esso. È solo una cattiva idea in quanto impedisce al compilatore di proteggerti dal spararti ai piedi e rende il tuo codice più difficile da leggere. Cerca sempre di aiutare il compilatore a aiutarti mantenendo i tipi il più a lungo possibile a meno che tu non abbia una buona ragione per non farlo.

modificare

Oh, e per completezza, puoi permettere che degrada a un puntatore, ma questo disaccoppia l'array dal numero di elementi che contiene. Questo viene fatto molto in C / C ++ e di solito viene mitigato passando il numero di elementi nell'array. Tuttavia, il compilatore non può aiutarti se commetti un errore e passi il valore sbagliato al numero di elementi.

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

Invece di passare la dimensione, puoi passare il puntatore di fine, che punterà a uno oltre la fine dell'array. Questo è utile perché rende qualcosa che è più vicino agli algoritmi std, che prendono un puntatore di inizio e fine, ma ciò che ritorni ora è solo qualcosa che devi ricordare.

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

In alternativa, puoi documentare che questa funzione richiederà solo 5 elementi e spera che l'utente della tua funzione non faccia nulla di stupido.

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

Si noti che il valore restituito ha perso il tipo originale ed è degradato a un puntatore. Per questo motivo, ora sei da solo per assicurarti di non sovraccaricare l'array.

Potresti passare a std::pair<int*, int*>, che puoi usare per inizio e fine e passarlo, ma poi smette davvero di sembrare un array.

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

Abbastanza divertente, questo è molto simile a come std::initializer_listfunziona (c ++ 11), ma non funzionano in questo contesto.


3

il modo più semplice per farlo è restituirlo come riferimento, anche se non si scrive il simbolo '&', viene automaticamente restituito come riferimento

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

  }

2
int *fillarr(int arr[])

Puoi comunque usare il risultato come

int *returned_array = fillarr(some_other_array);
if(returned_array[0] == 3)
    do_important_cool_stuff();

Non credo che "int [] fillarr ..." sia legale. 'Int * fillarr' è ciò che useresti a causa dell'equivalenza del puntatore di array.
dal

1

Come sopra indicato, i percorsi sono corretti. Ma penso che se restituiamo semplicemente una variabile di matrice locale di una funzione a volte restituisce valori di immondizia come suoi elementi.

per evitare che dovevo creare l'array in modo dinamico e procedere. Qualcosa del genere.

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

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




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))


0

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

C ++ non consente di restituire un intero array come argomento a una funzione. Tuttavia, è possibile restituire un puntatore a un array specificando il nome dell'array senza un indice.

  1. Se si desidera restituire un array a dimensione singola da una funzione, è necessario dichiarare una funzione che restituisce un puntatore come nell'esempio seguente:
int * myFunction()    {
   .
   .
   .
}
  1. C ++ non consiglia di restituire l'indirizzo di una variabile locale all'esterno della funzione, pertanto è necessario definire la variabile locale come variabile statica.

Applicando queste regole alla domanda attuale, possiamo scrivere il programma come segue:

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

L'output sarà:

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

0

e che mi dici di:

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

    return f;
}

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

0

In realtà quando si passa un array all'interno di una funzione, il puntatore all'array originale viene passato nel parametro della funzione e quindi le modifiche apportate all'array all'interno di quella funzione vengono effettivamente eseguite sull'array originale.

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

Eseguilo e vedrai le modifiche


1
Si prega di utilizzare una corretta espressione inglese (invece di te) e omettere frasi vuote come "amico".
hellow,

Inoltre: "allora in realtà viene passato come riferimento" è sbagliato. La variabile ystessa viene passata come copia di se stessa, ma poiché è un puntatore, opererai direttamente sull'array. Modifica la tua risposta
hellow,

stackoverflow.com/questions/5573310/… TL; DR "Pertanto, le due forme sono identiche."
hellow

Sì, è tecnicamente un array, hai ragione, ma ciò che viene copiato è un puntatore all'array, non all'array stesso.
hellow

0

Ecco un esempio completo di questo tipo di problema da risolvere

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

-2

Basta definire un tipo [] come valore di ritorno, come:

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

        string[] x = {one, two};


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

        return x;
    }

. . . chiamata di funzione:

string[] y;
y = functionReturnValueArray(stringOne, stringTwo)

5
Questo non è C ++
Adrian,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.