Domanda

Quando abbiamo inizializzare un array come questo int a[5] = {0}, il compilatore rende tutti i 5 elementi 0. Questo è veramente buono, compact-inizializzazione e caratteristica utile.

Ma mi chiedo perché il compilatore non inizializza int a[5]={1} simile? Perché non fare tutti i 5 elementi 1? Perché il Principio non si è? Non sarebbe stata una caratteristica impressionante? Non è forse manca?

Inoltre, se il numero di elementi nella inizializzatore è inferiore alla dimensione della matrice, quindi la compilazione potrebbe inizializzare i restanti elementi con l'ultimo elemento inizializzatore. Mezzi, int a[5]={1,2,3} equivale a int a[5]={1,2,3,3,3}. E allo stesso modo, int a[10]={1,2,3,0} è equivalente a int a[10]={1,2,3,0,0,0,0,0,0,0};.

sarebbe tutto non sia una caratteristica impressionante se i mandati standard esso? O c'è alcuna motivazione positive per questo caratteristica mancante?


E c'è qualcosa che si chiama designato inizializzatore a C99, che viene utilizzato come:

inizializzatori designati può essere combinato con inizializzatori regolari, come nel seguente esempio:

int a[10] = {2, 4, [8]=9, 10}

In questo esempio, a [0] è inizializzato a 2, un 1 viene inizializzata a 4, a [2] per una [7] vengono inizializzati a 0, e una [9] è inizializzato a 10.

Molto interessante. Ma anche questa funzione non è in C ++.

È stato utile?

Soluzione

che personalmente trovo più "logica" (cioè semplice) con un valore predefinito fisso di inizializzazione invece di un'altra regola di ripetere ultimo solo per gli array. Che possono apparire "pratico" (cioè utile), ma è più logico IMO complesso.

Detto questo però penso che stai facendo un grande errore nel tentativo di applicare la logica di un linguaggio come C ++.

C ++ è un linguaggio complesso le cui regole sono il risultato di una lunga storia dell'evoluzione, e la sua forma attuale è il risultato del lavoro di molte persone e anche di comitati formali (l'ultima parte da solo potrebbe spiegare nulla ).

Un linguaggio come il C ++ non può essere dedotta dalla logica, deve essere studiato come la storia. A meno che siate Hari Seldon non c'è davvero nessun modo si può dedurre la storia usando il ragionamento logico.

Ci sono luoghi di C ++ in cui si sta andando a soffrire molto se si tenta di utilizzare la logica invece di studiare. Solo per citarne alcuni ...

  • Perché è statica spedizione di default (cioè sbagliato )?
  • Perché non c'è parola chiave per il puntatore nullo?
  • Perché la differenza di due unsigned non è firmato?
  • Perché una somma tra un firmato e un unsigned non è firmato?
  • Se i mezzi non firmati "elemento di Z_ {2 ^ n} " allora perché le dimensioni sono senza segno ?
  • Perché std::string s; s=3.141592654; è perfettamente valido C ++?
  • Perché in C ++ 0X i = i++ + 1; è un comportamento indefinito e i = ++i + 1; è valida?
  • Perché non lo fa double x=3.14; int y(int(x)); y media sarà di 3?

Altri suggerimenti

Perché non fare tutti i 5 elementi 1?

Perché sei equivoco cosa significa {}. (In realtà, in C ++ il modo migliore per farlo è {} piuttosto che {0}). Il {0} sintassi non significa che si desidera che tutti gli elementi del set aggregata a zero. Piuttosto, si dice che si desidera un aggregato con il primo elemento di zero assegnato alla variabile indicata (che può essere sia una matrice o un tipo di classe in C ++). Poiché l'aggregato ha solitamente più campi di valore che uno a zero, gli elementi rimanenti nell'aggregato sono predefinito costruiti . Il valore predefinito di un integrato o di tipo POD è quello di impostare tutti i campi a zero, in modo che hai impostato in modo efficace dell'intero aggregato a zero.

Per quanto riguarda il motivo per cui in particolare, considerare quanto segue. Secondo l'attuale standard, nessuna delle affermazioni sotto fallirà:

struct abc
{
    char field1;
    int field2;
    char field3;
};

int main()
{
    abc example = {'a', static_cast<int>('b')};
    //All three asserts pass
    assert(example.field1 == 'a');
    assert(example.field2 == static_cast<int>('b'));
    assert(example.field3 == '\0');

    int example2[3] = {static_cast<int>('a'), 42};
    assert(example2[0] == static_cast<int>('a'));
    assert(example2[1] == 42);
    assert(example2[2] == 0);
}

Che cosa vi aspettate il valore di field3 di essere nella vostra proposta di modifica di serie? Anche se si definisce come l'ultimo elemento della inizializzatore di aggregazione come hai mostrato in precedenza, che sta andando a rompere la compatibilità con il codice che assume il resto degli elementi sono costruiti predefinito esistente.


EDIT:. appena realizzato che la vostra domanda viene posta in termini di matrici - ma la risposta è la stessa sia con le strutture o array, in modo che non ha molta importanza

EDIT2:. Per rendere questo più in linea con lo standard, i riferimenti a classe / struttura sono stati sostituiti con "aggregato" di seguito, che copre i casi di strutture e array

Sì, potrebbe hanno fatto, ma non l'hanno fatto, ed è troppo tardi per cambiare tale comportamento. Le decisioni dietro C e C ++ sono state fatte con il pensiero dato a prestazioni e minimalismo quasi a ogni passo, quindi immagino che, se non altro, entra in gioco anche qui.

Una tale caratteristica solo non mi sembra come tutto ciò che impressionante. E 'un semplice pezzo di zucchero sintattico, e raramente ho trovato la necessità di inizializzare un array simile a qualcosa di diverso da 0 in ogni caso.

librerie di runtime tipici forniscono una caratteristica che lo rende facile da inizializzare i dati a 0. In termini generali, questo viene memorizzato in una specifica sezione nel file eseguibile, organizzato dal compilatore e linker. All'avvio del programma, il codice di avvio usi runtime qualcosa come memset() per cancellare tutti i dati inizializzati a 0. Ciò significa che i byte a zero non devono essere conservati all'interno dell'eseguibile stesso.

Il contrario è che se si inizializza dati a qualcosa di diverso zero, allora i byte per che i dati devono essere memorizzati nel file eseguibile per sé, dal momento che l'initialiser automatico solo inizializza a zero.

Quindi, se si dovesse dichiarare una grande varietà di char (diciamo un megabyte?) E l'inizializzazione con, diciamo, {0}, allora non ci sarebbe byte memorizzati nel file eseguibile per tale matrice. D'altra parte, se si dovesse inizializzare con {1} sotto il vostro schema, un megabyte di byte 1 dovrebbe essere memorizzati nel file eseguibile stesso. Modificando un carattere nella lista initialiser, la dimensione degli aumenti di eseguibili da un megabyte.

Credo che tale regime un violerebbe la principio di minima sorpresa .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top