Passando un array per riferimento


184

Come funziona il passaggio di un array allocato staticamente per riferimento?

void foo(int (&myArray)[100])
{
}

int main()
{
    int a[100];
    foo(a);
}

Ha (&myArray)[100]qualche significato o è solo una sintassi per passare qualsiasi array per riferimento? Non capisco parentesi separata seguita da parentesi quadre qui. Grazie.


Esiste una relazione Rvalue to Lvalue con i parametri della funzione?
John DB,


Risposte:


228

È una sintassi per i riferimenti di array: è necessario utilizzare (&array)per chiarire al compilatore che si desidera un riferimento a un array, piuttosto che l'array (non valido) di riferimenti int & array[100];.

EDIT: alcuni chiarimenti.

void foo(int * x);
void foo(int x[100]);
void foo(int x[]);

Questi tre sono modi diversi di dichiarare la stessa funzione. Sono tutti considerati come prendere un int *parametro, puoi passare loro qualsiasi array di dimensioni.

void foo(int (&x)[100]);

Questo accetta solo array di 100 numeri interi. È possibile utilizzare in modo sicuro sizeofsux

void foo(int & x[100]); // error

Questo è analizzato come un "array di riferimenti" - che non è legale.


Perché non possiamo avere una serie di riferimenti, ad esempio int a, b, c; int arr[3] = {a, b, c};?
Vorac,

4
Ah, ho scoperto il perché .
Vorac,

2
Qualcuno potrebbe spiegare perché void foo(int & x[100]);viene analizzato come "array di riferimenti" per favore? È perché la regola "da destra a sinistra"? Se sì, sembra non essere coerente con il modo in cui void foo(int (&x)[100]);viene analizzato come "riferimento a un array". Grazie in anticipo.
zl9394,

3
Non è da destra a sinistra, è capovolto e [] si lega più stretto di &.
Philipxy,

48

È solo la sintassi richiesta:

void Func(int (&myArray)[100])

^ Passa un array di 100 intper riferimento il nome dei parametri è myArray;

void Func(int* myArray)

^ Passa un array. La matrice decade in un puntatore. In questo modo perdi le informazioni sulle dimensioni.

void Func(int (*myFunc)(double))

^ Passa un puntatore a funzione. La funzione restituisce an inte accetta a double. Il nome del parametro è myFunc.


Come passiamo un array di dimensioni variabili come riferimento?
Shivam Arora,

@ShivamArora Si modella la funzione e si rende la dimensione un parametro modello.
Martin York,

24

È una sintassi. Nella funzione sono necessarie le int (&myArray)[100]parentesi che racchiudono il simbolo &myArray. se non li usi, passerai un array of referencese questo perché il fatto subscript operator []ha la precedenza più alta sul & operator.

Per esempio int &myArray[100] // array of references

Quindi, usando type construction ()dici al compilatore che vuoi un riferimento a un array di 100 numeri interi.

Per esempio int (&myArray)[100] // reference of an array of 100 ints


"se non li usi, passerai un array of references" - che ovviamente non può esistere, quindi otterrai un errore di compilazione. È divertente per me che le regole di precedenza degli operatori insistano sul fatto che ciò debba avvenire comunque per impostazione predefinita.
underscore_d

C'è qualche altro tutorial sul tipo di costruzione ()?
Chief Shifter,

Grazie, avevo bisogno di una spiegazione che includesse il motivo della precedenza dell'operatore, che dà un senso al perché dovrebbe essere fatto in questo modo.
cram2208

4

Le matrici sono di default passate da puntatori. Puoi provare a modificare un array all'interno di una chiamata di funzione per una migliore comprensione.


2
Le matrici non possono essere passate per valore. Se la funzione riceve un puntatore, un array decade in un puntatore al suo primo elemento. Non sono sicuro di cosa stai cercando di dire qui.
Ulrich Eckhardt,

@UlrichEckhardt Sto cercando di dire che "Le matrici non possono essere passate per valore" come hai detto prima, sono di default passate per riferimento
Eduardo A. Fernández Díaz

8
Gli array non vengono passati né per valore né per riferimento. Sono passati da puntatori. Se le matrici vengono passate per riferimento per impostazione predefinita, non avrai problemi a utilizzare sizeof su di esse. Ma non è così. Le matrici decade in puntatori quando passano in una funzione.
user3437460,

2
Le matrici possono essere passate per riferimento O degradando a un puntatore. Ad esempio, usando char arr[1]; foo(char arr[])., arr si degrada a un puntatore; durante l'utilizzo char arr[1]; foo(char (&arr)[1]), arr viene passato come riferimento. È da notare che la forma precedente è spesso considerata mal formata poiché la dimensione è persa.
zl9394,

Ri, "Le matrici sono ... passate da puntatori." Tale descrizione suona al massimo non convenzionale e può essere fonte di confusione per i neofiti. Il nome di una variabile di matrice è un'espressione valida il cui valore è un puntatore al primo membro della matrice. Se hai qualche funzione foo(T* t)e hai un array T a[N];allora quando scrivi foo(a);penso che sarebbe più corretto dire che stai passando un puntatore, non passando un array, e stai passando il puntatore per valore.
Solomon Slow

1

Di seguito viene creata una funzione generica, prendendo come riferimento un array di qualsiasi dimensione e tipo:

template<typename T, std::size_t S>
void my_func(T (&arr)[S]) {
   // do stuff
}

gioca con il codice.

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.