2010-07-13 47 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:反例。

相关问题