为什么Pascal const数组实际上不是常量?

时间:2010-07-13 19:26:10

标签: arrays const pascal freepascal

  Program ConstTest;
  Const constVar = 1;
  Begin
    constVar := 3;
    WriteLn(constVar);
  End.

很明显上面的代码不会编译,因为改变常量的值是不对的。 但是,下面的代码将编译,并返回“1; 5; 3;”,即使数组是const:

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.

那么,是什么导致了这种行为呢?为什么常数实际上不是常数?

我正在使用FreePascal Compiler 2.2.0 for Win32。

2 个答案:

答案 0 :(得分:11)

你有一个类型常量。类型常量不同于普通常量(a.k.a。真常量),这就是你的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+}

以后是否重新打开它取决于你。


类型常量是可修改的,因为它们存储在内存中的方式。实际上,它是因为它们存储在内存中,它们最初是可修改的。普通常量不作为不同的对象存储在内存中。当编译器遇到程序中使用的普通常量时,它会将其替换为常量值,就像你在其位置使用了一个文字一样。另一方面,类型常量驻留在内存中它自己的位置,当你在代码中引用它时,它的值从内存中读取,就像使用任何其他变量一样。如果没有可用于文字的语法,则使用类型化常量 - 例如,您不能拥有数组或记录文字。

答案 1 :(得分:0)

好吧,如果你也知道C,这里有一些类比:

在[Turbo / Free] Pascal中,写下这样的东西:

const
     MIN = 5;
     MAX = 10;

相当于在C中执行此操作:

#define MIN 5
#define MAX 10

也就是说,它是一个编译时符号替换,就像其他海报所说的那样。

对于记录和数组(类型常量),“const”表达式只是初始化与链接符号相关联的内存块的一种方式。

TODO:反例。