Dichiarazione e assegnazione di array C?

Ho fatto una domanda simile su structs qui, ma sto cercando di capire come C gestisce cose come l’assegnazione di variabili e perché non è consentito assegnarle a vicenda se sono funzionalmente uguali.

Diciamo che ho due array:

int x[10]; int y[10]; 

Perché x = y non verrà compilato? Se sono entrambi la stessa “firma” come quella, allora non dovresti essere in grado di assegnarli avanti e indietro?

Posso dichiararli in un modo che mi permetterebbe di farlo in C? Per me è logico che tu sia in grado di farlo, ma forse c’è un modo in cui questo può essere fatto? I typedef per le strutture sembravano essere la soluzione, sarebbe lo stesso per la dichiarazione e l’assegnazione dell’array?

Apprezzo il tuo aiuto ragazzi, sono nuovo di Stackoverflow ma è stata una risorsa davvero buona per me finora!

In parole semplici, gli array non sono assegnabili. Sono un “valore non modificabile”. Questo ovviamente pone la domanda: perché? Si prega di fare riferimento a questa domanda per ulteriori informazioni:

Perché il C ++ supporta l’assegnazione degli array di membri all’interno delle strutture, ma non in generale?

Gli array non sono puntatori. x qui si riferisce ad un array, sebbene in molte circostanze questo “decadimento” (sia convertito implicitamente) in un puntatore al suo primo elemento. Allo stesso modo, anche y è il nome di un array, non un puntatore.

Puoi eseguire l’assegnazione dell’array all’interno delle strutture:

 struct data { int arr[10]; }; struct data x = {/* blah */}; struct data y; y = x; 

Ma non puoi farlo direttamente con gli array. Usa memcpy .

 int x [sz]; int *y = x; 

Questo compila e y sarà lo stesso di x .

Alcuni messaggi qui dicono che il nome di una matrice produce l’indirizzo del suo primo elemento. Non è sempre vero:

 #include  int main(void) { int array[10]; /* * Print the size of the whole array then the size of a pointer to the * first element. */ printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]); /* * You can take the address of array, which gives you a pointer to the whole * array. The difference between ``pointer to array'' and ``pointer to the * first element of the array'' matters when you're doing pointer arithmetic. */ printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1)); return 0; } 

Produzione:

 40 4 0xbfbf2ca4 0xbfbf2c80 

Per assegnare gli array dovrai assegnare i valori all’interno dell’array.

vale a dire. x = y è equivalente a

 for(int i = 0; i < 10 < ++i) { x[i] = y[i]; } 

Nel tentativo di integrare la risposta di Blank, ho ideato il seguente programma:

 localhost:~ david$ cat test.c #include  #include  int main (int argc, char * argv []) { struct data { int c [2]; } x, y; xc[0] = xc[1] = 0; yc[0] = yc[1] = 1; printf("xc %p %i %i\n", xc, xc[0], xc[1]); printf("yc %p %i %i\n", yc, yc[0], yc[1]); x = y; printf("xc %p %i %i\n", xc, xc[0], xc[1]); printf("yc %p %i %i\n", yc, yc[0], yc[1]); return 0; } 

Quando viene eseguito, viene visualizzato quanto segue:

 xc 0x7fff5fbff870 0 0 yc 0x7fff5fbff860 1 1 xc 0x7fff5fbff870 1 1 yc 0x7fff5fbff860 1 1 

Il punto è illustrare come avviene la copia dei valori delle strutture.

Quando si dice “int x [10]” sta dicendo, “riservare un po ‘di spazio per 10 interi e passarmi un puntatore alla posizione”. Quindi, perché la copia abbia un senso, è necessario operare sulla memoria puntata da, piuttosto che sul “nome della posizione di memoria”.

Quindi per copiare qui useresti un ciclo for o memcpy ().

Ho usato i compilatori C dove questo si sarebbe compilato bene … e quando si esegue il codice farebbe x puntare alla matrice di y.

Vedete, in C il nome di un array è un puntatore che punta all’inizio della matrice. In effetti, gli array e i puntatori sono essenzialmente intercambiabili. Puoi prendere qualsiasi puntatore e indicizzarlo come un array.

Ai tempi in cui C era in via di sviluppo nei primi anni ’70, era pensato per programmi relativamente piccoli che erano appena al di sopra del linguaggio di assemblaggio nell’astrazione. In quell’ambiente era dannatamente comodo poter andare avanti e indietro tra l’indicizzazione degli array e la matematica dei puntatori. La copia di interi array di dati, d’altra parte, era una cosa molto costosa da fare, e difficilmente qualcosa da incoraggiare o estrarre dall’utente.

Sì, in questi tempi moderni sarebbe più sensato avere il nome dell’array come abbreviazione di “the whole array”, piuttosto che “un ponter in prima fila”. Tuttavia, C non è stato progettato in questi tempi moderni. Se vuoi una lingua che fosse, prova Ada. x: = y fa esattamente quello che ti aspetteresti; copia i contenuti di una matrice sull’altro.