2010-02-20 15 views
7

Supponiamo che io sono una serieRestituisce un array in C++

int arr[] = {...}; 
arr = function(arr); 

ho la funzione di

int& function(int arr[]) 
{ 
//rest of the code 
     return arr; 
} 

Che errore sto facendo qui ??

+2

Perché sei (o solo uno sviluppatore) a scrivere questo pazzo codice? : \ – kennytm

+0

@ manugupt1: è intenzione di passare l'array nella funzione come copia? –

risposta

7
int& function(int arr[]) 

In questa funzione arr è un puntatore, e non c'è modo per trasformarlo in un array di nuovo. È lo stesso

int& function(int* arr) 

int arr[] = {...}; 
arr = function(arr); 

Assumendo che la funzione è riuscito a restituire un riferimento alla matrice, questo ancora non funzionerebbe. Non è possibile assegnare a un array. Nella migliore delle ipotesi si potrebbe associare il risultato di un "riferimento di una serie di X int" (utilizzando un typedef perché la sintassi otterrebbe molto brutta altrimenti):

typedef int ten_ints[10]; 

ten_ints& foo(ten_ints& arr) 
{ 
    //.. 
    return arr; 
} 

int main() 
{ 
    int arr[10]; 
    ten_ints& arr_ref = foo(arr); 
} 

Tuttavia, non è del tutto chiaro che cosa il codice nel tuo domanda dovrebbe raggiungere. Qualsiasi modifica apportata all'array in funzione sarà visibile al chiamante, quindi non c'è motivo di provare a restituire l'array o assegnarlo all'array originale.


Se si desidera un array di dimensioni fisse che è possibile assegnare a passare e per valore (con i contenuti da copiare), non c'è std::tr1::array (o boost::array). std::vector è anche un'opzione, ma quella è una matrice dinamica, quindi non è un equivalente esatto.

1
  • Un array come argomento è in realtà un puntatore. Gli array vengono automaticamente "castati" ai puntatori se vengono forniti come argomento
  • Non è possibile assegnare un array a un altro array in C/C++. Dovrai usare una memcpy o un ciclo per copiare i valori.
  • Se la funzione modifica l'argomento arr, in realtà modifica il valore della variabile arr fornita dal chiamante. Ancora una volta perché l'array è in realtà un puntatore. Quindi nel chiamante arr è assegnato a arr, che è inutile qui.
4

La semantica del passaggio e del ritorno di array può essere abbastanza confusa. Usa invece un vettore std ::.

+0

o boost :: array, se disponibile. – Macke

+9

Anche se questo è certamente un buon consiglio, ** non risponde nemmeno in remoto alla domanda ** .. –

+0

@Andreas "Che errore sto facendo qui?" - l'errore di non usare un vettore. –

3

Si sta restituendo un riferimento a un int, non un riferimento a un array.

desiderato:

(int*)& function(int arr[]) 
{ 
    /// rest of the code 
    return arr; 
} 

Detto questo, come altri già detto, questo non è buona pratica.

+3

In realtà ciò restituisce un riferimento a un puntatore e "arr" non è neanche un array. –

+1

Oltre a ciò che dice @gf, anche questo è un errore di sintassi. –

0

Bene, arr è compatibile con int*, non int&. Il tuo codice non verrà compilato. Forse volevi return arr[0]?

6

Come altri hanno detto, ci sono opzioni migliori come i contenitori STL e la domanda più interessante è il motivo per cui è necessario restituire l'array a una funzione che già lo ha in ambito.

Detto questo, non è possibile passare o restituire le matrici per valore e la necessità di evitare la matrice decadente a un puntatore (si veda ad esempio here), sia utilizzando puntatori o riferimenti ad esso:

int (&f(int (&arr)[3]))[3] 
{ 
    return arr; 
} 

Se non si desidera hard-code le dimensioni, è possibile utilizzare le funzioni del modello:

template<size_t n> 
int (&f(int (&arr)[n]))[n] 
{ 
    return arr; 
} 
+0

Questa è una sintassi seriamente _twisted_. Ti meriti molti complimenti per averlo ottenuto proprio qui. Mi sento libero di usare typedef ora che so _come potresti averlo scritto al compilatore senza _... +1 – sehe

+0

Supponendo che mi piacerebbe codificare un getter per una matrice di dimensioni fisse e voglio il metodo così come l'array di riferimento essere const - come lo farei sintatticamente? In questo modo: int const (e GetArray() const) [3] {return mArray; }? – Bjoern

+0

@Bjoern: 'typedef int A [3]; const A m; const A & f() const {return m; } '? –

0

usa std :: vector come questo.

std::vector<int> function(const std::vector<int>& arr) 
{ 
    return arr; 
} 

Un array come

int arr[] = {...}; 

non è utile per essere restituiti da una funzione perché non è in grado di riprodursi.

0

se non necessario, non utilizzarlo.si può solo passa un riferimento di un array, come ad esempio:

void foo(std::vector<int> &v) { 
    for (int i = 0; i < 10; ++ i) { 
     v.push_back(i); 
    } 
} 

se si utilizza:

std::vector<int> foo() { 
    std::vector<int> v; 
    for (int i = 0; i < 10; ++ i) 
     v.push_back(i); 

    return v; 
} 

ci sarà un processo di copia del contenitore, il costo è costoso.

proposito: NRVO forse eliminare il costo

1

Penso che la soluzione migliore è restituirla come puntatore a un array. Ecco un esempio:

{ 
    ... 
    int newLength = 0; 
    int* arr2 = ChangeArray(arr, length, newLength); 
    ... 
    delete[] arr2; 
} 

int* ChangeArray(int arr[], int length, int& newLength) 
{ 
    // reversing the number - just an example 
    int* newArr = new int[length]; 
    for(int i = 0; i < length; i++) 
    { 
     newArr[i] = arr[length-i-1]; 
     newLength++; 
    } 
    return newArr; 
} 
3

seguenti lavori e non sembra disordinato o mis-comprensibile!

int* returnarray(int a[]) 
{ 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     a[i] *= 2; 
    } 
    return a; 
} 

int main(int argc, char* argv[]) 
{ 
    int arr[3] = {1,2,3}; 
    int* p = returnarray(arr); 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     cout << "p[" << i << "] = " << p[i] << endl; 
    } 
     cin.get(); 
     return 0; 
}