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

定数の値を変更するのは正しくないため、上記のコードがコンパイルされないことは明らかです。ただし、次のコードはコンパイルされ、配列がconstであっても、「1;5;3;」を返します。

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を使用しています。

4

2 に答える 2

12

そこにあるのは型付き定数です。型付き定数は、通常の定数(別名真の定数) とは異なりますconstVar。に型を指定する必要がないことに注意してくださいconstVar。持っていた場合は、コンパイラーが新しい値をそれに割り当てることもできることがわかります。

const
  constVar: Integer = 1;

Free Pascal のマニュアルでは、型付き定数について説明しています。

通常の定数とは異なり、実行時に値を割り当てることができます。これは、初期化された変数のサポートに置き換えられた Turbo Pascal の古い概念です。詳細な説明については、セクション4.4の183ページを参照してください。

型付き定数への値の割り当てのサポートは、{$J}ディレクティブによって制御されます。オフに切り替えることもできますが、デフォルトではオンになっています (Turbo Pascal との互換性のため)。初期化された変数は常に許可されます。

初期化された変数の場合、宣言でconstに置き換えます。varスコープに入るとその値を取得します。$Jまたは、型付き定数宣言の前にディレクティブをオフにします。

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

後でオンに戻すかどうかはあなた次第です。


型付き定数は、メモリに格納される方法により変更可能です。実際、それらが元々変更可能だったのは、それらがメモリに格納されているためです。通常の定数は、個別のオブジェクトとしてメモリに格納されません。コンパイラは、プログラムで使用されている通常の定数に遭遇すると、その場所にリテラルを使用したかのように、インラインで定数の値に置き換えます。一方、型付き定数はメモリ内の独自の場所に常駐し、コード内で型付き定数を参照すると、他の変数を使用する場合と同様に、その値がメモリから読み取られます。リテラルに使用できる構文がない場合は、型付き定数を使用します。たとえば、配列リテラルやレコード リテラルを使用することはできません。

于 2010-07-13T21:55:35.807 に答える
0

Cも知っているなら、いくつかの類推があります:

[Turbo/Free] Pascal では、次のように記述します。

const
     MIN = 5;
     MAX = 10;

Cでこれを行うのと同等です:

#define MIN 5
#define MAX 10

つまり、他のポスターが言うように、コンパイル時のシンボルの置き換えです。

レコードと配列 (型付き定数) では、"const" 式は、リンカー シンボルに関連付けられたメモリ ブロックを初期化する方法にすぎません。

TODO: 反例。

于 2012-04-21T04:05:25.663 に答える