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

很明顯,上面的代碼不會編譯,因爲改變常量的值是不對的。 然而,下面的代碼編譯,將返回 「1:5:3;」,即使數組是一個const:爲什麼Pascal常量數組實際上不是常量?

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. 

那麼,是什麼原因導致這種行爲?爲什麼常量不是一個常量?

我爲Win32使用FreePascal編譯器2.2.0。

+0

另請參閱http://stackoverflow.com/questions/48934/in-delphi-7-why-can-i-assign-a-value-to-a-const和http://stackoverflow.com/questions/2714365 /德爾福所有常數,是常數,但是,一些 - 是 - 更常高於其他人。 – 2010-07-13 21:57:47

回答

11

你在那裏有一個鍵入的常量。類型常量不同於普通常量(又名真常數),這就是你的constVar。注意你不需要在constVar上指定類型;如果你有,你可能會看到,編譯器允許您指定的新值給它,太:

const 
    constVar: Integer = 1; 

The Free Pascal manual描述類型的常量:

相反,普通的常量,值可以被分配到他們在運行時。這是Turbo Pascal的一箇舊概念,它已被支持初始化變量所取代:有關詳細說明,請參見4.4,第183頁。

支持爲鍵入的常量賦值通過{$J}指令進行控制:它可以關閉,但默認情況下打開(用於Turbo Pascal兼容性)。初始化的變量總是被允許的。

對於初始化變量,請在您的聲明中將const替換爲var。它將在進入範圍後得到它的價值。或者,先於類型化常量聲明關閉$J指令:

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

無論你打開它之後是你。


由於它們存儲在內存中的方式,類型化常量是可修改的。事實上,它是,因爲它們存儲在它們原來可以修改的內存中。普通常量不作爲不同的對象存儲在內存中。當編譯器遇到程序中使用的普通常量時,它會將其與常量的值一致地替換,就像您在其位置使用了文字一樣。另一方面,類型常量駐留在內存中的自己的位置,當您引用代碼中的某個常量時,它的值將從內存中讀取,就像使用任何其他變量一樣。例如,當沒有可用於文字的語法時,可以使用鍵入的常量 - 例如,不能有數組或記錄文字。

0

好吧,如果你也知道C,這裏有幾個比喻:

在[渦輪增壓/免費]帕斯卡,寫這樣的事情:

const 
    MIN = 5; 
    MAX = 10; 

是等價於C這樣做:

#define MIN 5 
#define MAX 10 

也就是說,這是一個編譯時代符號替換像其他海報說的。

對於記錄和數組(常量類型),「const」表達式只是一種初始化與鏈接器符號關聯的內存塊的方法。

TODO:反例。