2012-12-09 5 views
5

Sto leggendo di Gilles Dowek principi della programmazione languanges:Perché è possibile dichiarare una variabile senza un valore iniziale?

Dice che è anche possibile dichiarare una variabile senza dare un valore iniziale e anche che dobbiamo stare attenti a non utilizzare una variabile che è stata dichiarato senza un valore iniziale e a cui non è stato assegnato un valore. Questo produce un errore.

Nota: L'autore del libro menziona la possibilità di dichiarare variabili senza un valore iniziale su Java.

Quindi, perché è valida questa dichiarazione delle variabili? Quando lo userò?

+0

Credo che la risposta sia diversa dalla lingua alla lingua. –

+0

Sì, lo è. L'autore del libro afferma che questa funzione è valida in Java, modifico il post. –

+1

Buona domanda. Mi chiedo quale sia la logica? – xagyg

risposta

7

Ci sono molti motivi diversi per molte lingue diverse.

MEMORIA
Quando si dichiara una variabile, vuoi un po 'di memoria per contenere la variabile in. Ciò comporta che chiede il kernel del sistema operativo per la memoria, o un qualche tipo di programma di monitoraggio che tiene traccia della memoria. In breve, può essere un'operazione costosa. In molti casi, è preferibile allocare tutta la memoria necessaria per l'oggetto nello stesso momento e quindi assegnare qualsiasi valore deve essere assegnato ad esso in un secondo momento. In questo modo, puoi aumentare le prestazioni del programma nelle parti critiche. Questo caso d'uso è abbastanza comune che è consentita una funzionalità che consente la dichiarazione senza inizializzazione. Tuttavia, le buone pratiche affermano che in tutti gli altri casi è necessario inizializzare la variabile durante l'assegnazione.

Pensa all'assegnazione della memoria come a una burocrazia. C'è troppo lavoro di carta. Quindi, se sai che utilizzerai una grande quantità di memoria in un secondo momento, chiederai una grande quantità di memoria in anticipo in una singola transazione, invece di chiedere il kernel ogni volta successiva.

INIZIALIZZAZIONE CARO
Questo punto è molto simile al punto precedente. Supponiamo che tu abbia un milione di volte 1 milione di array. L'inizializzazione di tale array è una procedura costosa. Fare così con le impostazioni predefinite sarebbe stupidità, e quindi, una tale caratteristica, in cui la memoria viene allocata e quindi utilizzata secondo necessità.

Qui, è come se steste acquistando una quantità enorme di blocchi di lego per costruire qualcosa, ma volete comprarli in forme dello spiderman di default. Il negoziante o tu dovresti essere più duro per prenderli in forma di spiderman quando in ogni caso li rimodellerai più tardi.

5

Per esempio, si potrebbe avere qualcosa di simile:

int i; 
if (first_condition) 
    i = 1; 
elseif (second_condition) 
    i = 2; 
else 
    i = 0; 

La variabile dovrebbe essere dichiarata fuori del if per poter essere utilizzato in seguito, ma il suo valore è fissato all'interno delle if condizioni.

1

Qualcosa di simile:

//declare without giving value. 
int i; 

//set value 
i=9; 
+1

Questa non è la mia domanda, la mia domanda è: perché è possibile dichiarare una variabile senza un valore iniziale se ha un errore? –

+0

Non tutto darà errore ... Come int i; darà 0. Ma se lo fai Utente utente; Quindi più tardi String s = user.address; Ti dà errore – user903772

+0

@ user903772 le variabili locali non sono inizializzate su nulla, non sono definite ... "Le variabili locali sono leggermente diverse, il compilatore non assegna mai un valore predefinito a una variabile locale non inizializzata Se non puoi inizializzare la tua variabile locale dove è dichiarato, assicurati di assegnargli un valore prima di tentare di usarlo. L'accesso a una variabile locale non inizializzata comporterà un errore in fase di compilazione. " – xagyg

1

È possibile dichiarare un var vuoto per esempio in uno script di validazione,

$error=''; 
if(empty($_POST['first_name']{ 
$error=$error."You did not enter a name"; 

}

come questo, ma vorrei utilizzarla solo se il codice immediatamente dopo averlo riprogrammato, come sopra, in modo che non venga "smarrito".

3

Se si guarda veramente cosa succede quando si dichiara una variabile e si inizializza (assegna un valore iniziale), si vedrà che a livello di istruzione macchina, o codice byte per Java, c'è una quantità significativa di potenza computazionale utilizzato in entrambi questi passaggi.

  1. dichiara i mezzi variabili assegnazione memoria, creando un'istanza di tipo chiese, ecc ecc
  2. Poi inizializzazione quella posizione di memoria, richiede ancora più elaborazione per spostare il valore predefinito della posizione memoria allocata, come riempiendolo con 0 se il valore predefinito è 0. (Nota: quando la posizione della memoria casuale è assegnata a una variabile che la memoria potrebbe contenere qualsiasi modello, lasciata lì da un valore precedente)

Quindi, se l'utente utilizza inconsapevolmente una variabile senza prima dandogli un valore accettabile per il suo tipo, allora potrebbe esserci un errore se il valore che wa s non c'era corretto.

Quindi, se un linguaggio ti obbliga a inizializzare una variabile (o lo fa da solo) alla dichiarazione, riduce le possibilità di un errore lungo la linea, ma potrebbe sprecare potenza di elaborazione per qualcosa che non volevi davvero.

D'altra parte, se ti permette di dichiarare una variabile senza inizializzarla, ti dà il controllo e può risparmiare qualche potenza di calcolo per te, ma apre le possibilità di un errore. (Si supponga di avere uno scenario in cui il valore iniziale per la variabile dipende da alcune altre condizioni, che prenderanno in considerazione e assegneranno la variabile di conseguenza. In tal caso, l'inizializzazione della variabile alla dichiarazione potrebbe essere solo una potenza di elaborazione dei rifiuti).

Le lingue decidono quale percorso intraprendere, dipendono in gran parte da quello che considerano il loro potere.

se si tratta di dare al programmatore la possibilità di avere il controllo e di realizzare programmi altamente ottimizzati, di solito permetteranno di dichiarare vars senza inizializzare, oltre a più cose.

Ma se il linguaggio prevede di forzare il programmatore a scrivere più programmi privi di errori, prenderebbe l'altro percorso.

2

Se Java dovesse richiedere che i campi di un oggetto di classe devono sempre essere scritti prima che fossero lette, ciò richiederebbe che o

  • Il costruttore di un oggetto classe deve scrivere a tutti i campi di quell'oggetto , compresi quelli che il codice non leggerebbe mai senza averli scritti una seconda volta dopo; questo sarebbe sia brutto che inefficiente.

  • Ogni campo deve essere in grado di contenere un valore never been written diverso da qualsiasi altro valore che può essere scritto su di esso.

  • Il compilatore dovrebbe risolvere il problema di interruzione per determinare se un campo potrebbe essere letto senza essere stato scritto.

  • La lingua deve accettare la possibilità che un campo venga letto senza che il codice utente lo abbia scritto.

Di queste possibili scelte, # 4 è il meno cattivo.Per evitare comportamenti non definiti, Java definisce il comportamento di leggere un campo che non è mai stato scritto: conterrà un valore predefinito per il suo tipo.

+0

Solo i campi di istanza hanno valori predefiniti.Il tentativo di utilizzare un campo locale senza inizializzazione comporterà un errore di compilazione. Il fatto che i campi di istanza non debbano essere inizializzati è più una semplificazione del compilatore che una buona progettazione. Questa risposta lo spiega bene: https://stackoverflow.com/questions/1560685/why-must-local-variables-including-primitives-always-be-initialized-in-java –

+0

Forse avrei dovuto dire "istanza di classe" piuttosto di "oggetto di classe", ma non credo che le risposte a quell'altra domanda considerassero ciò che sarebbe necessario se il linguaggio richiedesse che i campi di istanza vengano scritti. Consentire al compilatore di generare codice senza dover risolvere il problema di interruzione o riservare un valore "mai stato scritto" per ogni campo può essere una "semplificazione", ma lo considererei più semplice come praticità. – supercat

1

Ok ecco un esempio. Attualmente sto impostando valori globali che sono impostati su persistente su un forum PDF. Per questa applicazione voglio utilizzare questi valori come archiviazione dei dati molto simile a un campo di testo. Non è il metodo migliore ma funziona per questo esempio. Piuttosto che compilare il mio forum con centinaia di campi di testo nascosti, posso impostare i valori come variabili globali persistenti.

Se il mio decelerazione iniziale è impostato su 0 o "" come valore della variabile che non mancherà di tenere i dati tra le sessioni. L'inizializzazione del forum reimposterà il valore su nulla. Proprio come gli script, i forum funzionavano in ordine. Riconoscerà prima tutti gli script nel documento, prima di assegnare valori a variabili successive. Pertanto è necessario dichiarare la variabile senza un valore, in modo che l'inizializzazione non sostituisca i valori.

In generale è buona norma tenere tutte le variabili in alto. È possibile dichiararli mentre si procede, ma ho scoperto che quando un nuovo elemento viene aggiunto a uno script, devo spostare le linee su e giù per mantenere pulito il mio codice. Se la variabile viene dichiarata quando viene usata, allora diventa molto facile usare una variabile prima che sia dichiarata, il che non funziona.

Inoltre

È efficiente assegnare valore quando dichiara, ma non generico valori posto titolare. Nella maggior parte degli script int non è semplice come dire int x = 5; Più spesso richiediamo dati come this.getField ("TextBox3"). Value; o qualche altro codice di linea. Assegnando un valore generico come "" o o true la tua funzione potrebbe funzionare anche se non hai correttamente utilizzato un valore. Non assegnando un valore, se non si riesce a utilizzare la variabile, la funzione fallirà consentendo di limitare le possibilità durante la risoluzione dei problemi. Se int x; è ancora NaN quando si utilizza x rispetto alla raccolta dei dati e le convalide sono probabilmente la fonte del problema.

In generale dichiarare tutti i valori nella parte superiore ed evitare di impostare valori generici a meno che non sia necessario. Se si intende definire i valori di x più tardi di non impostarlo su int x = 0;.