2010-07-13 5 views
10
Program ConstTest; 
    Const constVar = 1; 
    Begin 
    constVar := 3; 
    WriteLn(constVar); 
    End. 

È ovvio che il codice precedente non verrà compilato, perché non è giusto modificare il valore di una costante. Tuttavia, a seguito di codice compilato, e tornerà "1; 5; 3;", anche se la matrice è un const:Perché gli array cost di Pascal non sono effettivamente costanti?

Program ConstTest; 
    Const constArr:Array [1..3] Of ShortInt = (1,2,3); 
    Var i:ShortInt; 
    Begin 
    constArr[2] := 5; 
    For i:=1 To 3 Do WriteLn(constArr[i],'; '); 
    End. 

Allora, che cosa provoca questo comportamento? Perché una costante non è in realtà una costante?

Sto usando FreePascal Compiler 2.2.0 per Win32.

+0

Vedere anche http://stackoverflow.com/questions/48934/in-delphi-7-why-can-i-assign-a-value-to-a-const e http://stackoverflow.com/questions/2714365/Delphi-tutte-le costanti-sono-costante ma-some-sono-più-costante-che-altri. –

risposta

11

Quello che hai è una costante immessa. Le costanti digitate sono distinte da costanti ordinarie (a.k.a costanti reali), che è ciò che è il tuo constVar. Si noti come non è stato necessario specificare un tipo su constVar; se si ha, si può vedere che il compilatore permette di nuovi valori assegnati ad esso, troppo:

const 
    constVar: Integer = 1; 

The Free Pascal manual descrive costanti digitati:

Contrariamente a costanti ordinarie, del valore può essere assegnato a loro in fase di esecuzione. Questo è un vecchio concetto di Turbo Pascal, che è stato sostituito con il supporto per le variabili inizializzate: Per una descrizione dettagliata, vedere la sezione 4.4, pagina 183.

Il supporto per l'assegnazione di valori alle costanti digitate è controllato dalla direttiva {$J}: può essere disattivato, ma è attivo per impostazione predefinita (per compatibilità con Turbo Pascal). Le variabili inizializzate sono sempre consentite.

Per una variabile inizializzata, sostituire const con var nella dichiarazione. Otterrà il suo valore entrando nello scope. Oppure, spegnere la direttiva $J prima della costante digitato dichiarazione:

{$J-} 
const 
    constArr: array [1..3] of ShortInt = (1, 2, 3); 
{$J+} 

Sia che riaccenderlo dopo dipende da voi.


Le costanti digitate sono modificabili a causa del modo in cui sono memorizzate. Infatti, è perché sono memorizzati in memoria che erano originariamente modificabili. Le costanti ordinarie non sono archiviate in memoria come oggetti distinti. Quando il compilatore incontra una costante ordinaria usata nel tuo programma, la sostituisce in linea con il valore della costante, proprio come se avessi usato un letterale al suo posto. Una costante tipizzata, d'altra parte, risiede nella propria posizione in memoria, e quando si fa riferimento a uno nel codice, il suo valore viene letto dalla memoria, proprio come l'utilizzo di qualsiasi altra variabile. Si utilizzano costanti digitate quando non esiste una sintassi disponibile per un valore letterale, ad esempio non è possibile avere letterali di array o record.

0

Beh, se si sa anche C, ecco un paio di analogie:

In [Turbo/libero] Pascal, a scrivere qualcosa di simile:

const 
    MIN = 5; 
    MAX = 10; 

equivale a fare questo in C:

#define MIN 5 
#define MAX 10 

Cioè, è un simbolo di tempo di compilazione sostituire come dice l'altro poster.

Con record e matrici, (costanti digitate), l'espressione "const" è solo un modo per inizializzare un blocco di memoria associato a un simbolo del linker.

TODO: esempio contatore.