valore iniziale dell’array int in C

Quando dichiari un array in C come questo:

int array[10]; 

Qual è il valore iniziale degli interi ?? Sto ottenendo risultati diversi con diversi compilatori e voglio sapere se ha qualcosa a che fare con il compilatore o il sistema operativo.

Se la matrice è dichiarata in una funzione, il valore non è definito. int x[10]; in una funzione significa: assumere la proprietà dell’area di memroy 10-int-size senza eseguire alcuna inizializzazione. Se la matrice è dichiarata come globale o static in una funzione, tutti gli elementi vengono inizializzati a zero se non sono già inizializzati.

Come stabilito dallo standard, tutte le variabili statiche globali e di funzione vengono inizializzate automaticamente su 0. Le variabili automatiche non vengono inizializzate.

 int a[10]; // global - all elements are initialised to 0 void foo(void) { int b[10]; // automatic storage - contain junk static int c[10]; // static - initialised to 0 } 

Tuttavia, è buona norma inizializzare sempre manualmente la variabile di funzione, indipendentemente dalla sua class di memoria. Per impostare tutti gli elementi dell’array su 0 devi solo assegnare il primo elemento dell’array a 0 – gli elementi omessi verranno impostati automaticamente su 0:

 int b[10] = {0}; 

Perché i locals di funzione (class di memorizzazione auto ) non sono inizializzati quando tutto il resto è?

C è vicino all’hardware; questa è la sua più grande forza e il suo più grande pericolo. Il motivo per cui auto oggetti della class di memorizzazione auto hanno valori iniziali casuali è perché sono allocati nello stack e una decisione di progettazione è stata presa per non cancellarli automaticamente (in parte perché avrebbero bisogno di essere cancellati in ogni chiamata di funzione).

D’altra parte, gli oggetti non auto devono essere cancellati solo una volta. Inoltre, il sistema operativo deve comunque cancellare le pagine allocate per motivi di sicurezza. Quindi la decisione di progettazione qui era di specificare l’inizializzazione zero. Perché anche la sicurezza non è un problema con lo stack? In realtà è chiarito, all’inizio. La spazzatura che vedi proviene da precedenti istanze dei frame di chiamata del tuo programma e dal codice della libreria che hanno chiamato.

Il risultato finale è un codice veloce ed efficiente in termini di memoria. Tutti i vantaggi dell’assemblaggio senza il dolore. Prima che dmr avesse inventato C, “HLL” come Basic e interi kernel di SO erano realmente, letteralmente, implementati come giganteschi programmi di assemblaggio. (Con alcune eccezioni in luoghi come IBM.)

Secondo lo standard C, 6.7.8 (nota 10):

Se un object con durata di archiviazione automatica non è inizializzato in modo esplicito, il suo valore è indeterminato.

Quindi dipende dal compilatore. Con MSVC, le build di debug inizializzeranno le variabili automatiche con 0xcc, mentre le build non di debug non inizializzeranno affatto quelle variabili.

Nella maggior parte dei compilatori più recenti (ad esempio gcc / vc ++), i membri di array / struttura locali parzialmente inizializzati vengono inizializzati automaticamente su zero (int), NULL (stringa char / char), 0,000000 (float / double).

Oltre ai dati dell’array / struttura locale come sopra, anche i membri statici (globali / locali) e lo spazio globale mantengono la stessa proprietà.

 int a[5] = {0,1,2}; printf("%d %d %d\n",*a, *(a+2), *(a+4)); struct s1 { int i1; int i2; int i3; char c; char str[5]; }; struct s1 s11 = {1}; printf("%d %d %d %c %s\n",s11.i1,s11.i2, s11.i3, s11.c, s11.str); if(!s11.c) printf("s11.c is null\n"); if(!*(s11.str)) printf("s11.str is null\n"); 

In gcc / vc ++, l’output dovrebbe essere:

0 2 0 1 0 0 0,000000 s11.c è null s11.str è null

La dichiarazione delle variabili AC dice semplicemente al compilatore di mettere da parte e nominare un’area di memoria per te. Per le variabili automatiche, note anche come variabili stack, i valori in quella memoria non vengono modificati rispetto a quelli precedenti. Le variabili globali e statiche sono impostate su zero all’avvio del programma.

Alcuni compilatori in modalità di debug non ottimizzata impostano le variabili automatiche su zero. Tuttavia, nei nuovi compilatori è diventato comune impostare i valori su un valore errato noto in modo che il programmatore non scriva inconsapevolmente il codice che dipende dallo zero impostato.

Per chiedere al compilatore di impostare un array a zero per te, puoi scriverlo come:

 int array[10] = {0}; 

Meglio ancora è impostare la matrice con i valori che dovrebbe avere. Questo è più efficiente ed evita di scrivere nell’array due volte.

Testo da http://www.cplusplus.com/doc/tutorial/arrays/

SOMMARIO:

Inizializzazione di array. Quando si dichiara una matrice regolare di ambito locale (all’interno di una funzione, ad esempio), se non si specifica diversamente, i suoi elementi non verranno inizializzati su alcun valore per impostazione predefinita, quindi il loro contenuto sarà indeterminato finché non memorizzeremo alcun valore in essi. Gli elementi di array globali e statici, d’altra parte, sono automaticamente inizializzati con i loro valori di default, che per tutti i tipi fondamentali significa che sono pieni di zeri.

In entrambi i casi, locale e globale, quando dichiariamo un array, abbiamo la possibilità di assegnare valori iniziali a ciascuno dei suoi elementi racchiudendo i valori tra parentesi {}. Per esempio:

 int billy [5] = { 16, 2, 77, 40, 12071 };