宣言済みの定数

提供: Appmethod Topics
移動先: 案内検索

データ型、変数、定数:インデックス への移動

いくつかの種類の言語構文が、"定数" として参照されます。定数には、17 のような数値定数(数値とも呼ばれる)や "Hello World" のような文字列定数(文字列または文字列リテラルとも呼ばれる)があります。すべての列挙型は、列挙型の値を表す定数を定義します。TrueFalse、および nilのような、定義済みの定数もあります。最後に、変数のように宣言によって個別に作成される定数もあります。

宣言済みの定数は、真の定数 または 型付き定数 のいずれかです。これらの 2 種類の定数は、外見上は似ていますが、異なる規則が適用され、異なる目的で使用されます。

真の定数

真の定数は、値を変更できない宣言済みの識別子です。次に示すのはその例です。

const MaxValue = 237;

これは、整数 237 を返す MaxValue という定数を宣言しています。真の定数を宣言する構文は次のとおりです。

const identifier = constantExpression

ここで、"identifier" は有効な識別子であり、constantExpression はコンパイラがプログラムを実行せずに評価できる式です。

constantExpression が順序値を返す場合、値の型キャストを使って宣言済み定数の型を指定できます。次に示すのはその例です。

const MyNumber = Int64(17);

これは、整数 17 を返す Int64 型の MyNumber という定数を宣言しています。このようにしなければ、宣言済み定数の型は constantExpression の型になります。

  • constantExpression が文字列の場合、宣言済み定数は任意の文字列型と互換性があります。文字列の長さが 1 の場合は、任意の文字型とも互換性があります。
  • constantExpression が実数の場合、その型は Extended になります。整数の場合、その型は以下の表のようになります。

整数定数の型

定数の範囲(16 進数) 定数の範囲(10 進数) エイリアス
0
$FF
0
255

Byte

UInt8

0
$FFFF
0
65535

Word

UInt16

0
$FFFFFFFF
0
4294967295

Cardinal

UInt32LongWord

0
$FFFFFFFFFFFFFFFF
0
18446744073709551615

UInt64

-$80
 $7F
-128
 127

ShortInt

Int8

-$8000
 $7FFF
-32768
 32767

SmallInt

Int16

-$80000000
 $7FFFFFFF
-2147483648
 2147483647

Integer

Int32LongInt

-$8000000000000000
 $7FFFFFFFFFFFFFFF
-9223372036854775808
 9223372036854775807

Int64


32 ビットのネイティブ整数型

定数の範囲(16 進数) 定数の範囲(10 進数) 同等の型
-$80000000
 $7FFFFFFF
-2147483648
 2147483647

NativeInt

Integer

0
$FFFFFFFF
0
4294967295

NativeUInt

Cardinal


64 ビットのネイティブ整数型

定数の範囲(16 進数) 定数の範囲(10 進数) 同等の型
-$8000000000000000
 $7FFFFFFFFFFFFFFF
-9223372036854775808
 9223372036854775807

NativeInt

Int64

0
$FFFFFFFFFFFFFFFF
0
18446744073709551615

NativeUInt

UInt64


定数宣言の例をいくつか以下に示します。

const
  Min = 0;
  Max = 100;
  Center = (Max - Min) div 2;
  Beta = Chr(225);
  NumChars = Ord('Z') - Ord('A') + 1;
  Message = 'Out of memory';
  ErrStr = ' Error: ' + Message + '. ';
  ErrPos = 80 - Length(ErrStr) div 2;
  Ln10 = 2.302585092994045684;
  Ln10R = 1 / Ln10;
  Numeric = ['0'..'9'];
  Alpha = ['A'..'Z', 'a'..'z'];
  AlphaNum = Alpha + Numeric;

定数式

定数式は、コンパイラが定数式を含むプログラムを実行することなしに評価できる式です。定数式は次のものを含みます。数値、文字列、真の定数、および列挙型の値。特別な定数 TrueFalse、および nil。これらの要素と演算子、型キャスト、および集合構成子のみで構成された式。定数式に、変数、ポインタ、および以下の定義済み関数以外への関数呼び出しを含めることはできません。

Abs

High

Low

Pred

Succ

Chr

Length

Odd

Round

Swap

Hi

Lo

Ord

SizeOf

Trunc


この定数式の定義は、Object Pascal の構文仕様の複数の場所で使用されます。定数式は、次の場合に必要になります。グローバル変数の初期化、部分範囲型の定義、列挙型の値への順序の指定、デフォルト パラメータ値の指定、case 文の記述、および真の定数と型付き定数の宣言。

定数式の例を以下に示します。

100
'A'
256 - 1
(2.5 + 1) / (2.5 - 1)
'Embarcadero' + ' ' + 'Developer'
Chr(32)
Ord('Z') - Ord('A') + 1

リソース文字列

リソース文字列は、リソースとして格納され、プログラムを再コンパイルせずに変更できるように、実行可能ファイルまたはライブラリにリンクされます。

リソース文字列は、constresourcestring に置き換えられる以外は、他の真の定数のように宣言されます。= シンボルの右側の式は定数式で、文字列値を返さなくてはなりません。次に示すのはその例です。

resourcestring
  CreateError = 'Cannot create file %s';
  OpenError = 'Cannot open file %s';
  LineTooLong = 'Line too long';
  ProductName = 'Embarcadero Rocks';
  SomeResourceString = SomeTrueConstant;

型付き定数

型付き定数は、真の定数と異なり、配列型、レコード型、手続き型、およびポインタ型を保持できます。型付き定数は、定数式には使用できません。

型付き定数は、次のように宣言します。

const identifier: type = value

ここで、識別子は有効な識別子、型はファイル型およびバリアント型以外の型、値は型の式です。次に示すのはその例です。

const Max: Integer = 100;

ほとんどの場合、値は定数式でなければなりませんが、配列型、レコード型、手続き型、またはポインタ型の場合は、特別な規則が適用されます。

配列定数

配列定数を宣言するには、コンマで区切った配列要素の値をかっこで囲み、宣言の最後に指定します。これらの値は、定数式で表さなければなりません。次に示すのはその例です。

const Digits: array[0..9] of Char =
  ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

これは、文字の配列を保持する Digits という型付き定数を宣言しています。

インデックスが 0 から始まる文字配列は、多くの場合 NULL 終端文字列を表します。そのため、文字列定数が文字配列を初期化するために使用されます。したがって、前の宣言は次のようにより簡単に表すことができます。

const Digits: array[0..9] of Char = '0123456789';

多次元の配列定数を定義するには、各次元の値を、コンマで区切った別々のかっこの組で囲みます。次に示すのはその例です。

type TCube = array[0..1, 0..1, 0..1] of Integer;
const Maze: TCube = (((0, 1), (2, 3)), ((4, 5), (6,7)));

これは、Maze という配列を作成します。配列内の値は、次のようになります。

Maze[0,0,0] = 0
Maze[0,0,1] = 1
Maze[0,1,0] = 2
Maze[0,1,1] = 3
Maze[1,0,0] = 4
Maze[1,0,1] = 5
Maze[1,1,0] = 6
Maze[1,1,1] = 7

配列定数は、ファイル型の値をどのレベルにも含むことはできません。

レコード定数

レコード定数を宣言するには、宣言の最後のかっこ内に、各フィールドの値を フィールド名: 値 のように指定して、各フィールドをセミコロンで区切ります。値は、定数式で表さなければなりません。フィールドは、レコード型宣言に現れる順序でリストされなければなりません。タグ フィールドがある場合は、値を指定する必要があります。レコードが可変部分を持つ場合は、タグ フィールドによって選択された可変部分のみに値を指定することができます。

次に示すのはその例です。


type
  TPoint = record
     X, Y: Single;
  end;
  TVector = array[0..1] of TPoint;
  TMonth = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec);
  TDate = record
    D: 1..31;
    M: TMonth;
    Y: 1900..1999;
  end;
const
  Origin: TPoint = (X: 0.0; Y: 0.0);
  Line: TVector = ((X: -3.1; Y: 1.5), (X: 5.8; Y: 3.0));
  SomeDay: TDate = (D: 2; M: Dec; Y: 1960);

レコード定数は、ファイル型の値をどのレベルにも含むことはできません。

手続き定数

手続き定数を宣言するには、宣言する定数の型と互換性のある関数または手続きの名前を指定します。次に示すのはその例です。


function Calc(X, Y: Integer): Integer;
begin
  ...
end;

type TFunction = function(X, Y: Integer): Integer;
const MyFunction: TFunction = Calc;

これらの宣言を行うと、手続き定数 MyFunction を関数呼び出しに使用することができます。

I := MyFunction(5, 7)

nil を手続き定数に割り当てることもできます。

ポインタ定数

ポインタ定数を宣言する場合、コンパイル時に少なくとも相対アドレスに解決できる値に初期化しなければなりません。初期化する方法は、3 つあります。@ 演算子を使用する方法、nil を使用する方法、および(定数が PChar または PWideChar の場合)文字列リテラルを使用する方法です。たとえば、IInteger 型のグローバル変数である場合、次のように定数を宣言できます。

const PI: ^Integer = @I;

グローバル変数がコード セグメントの一部になっているので、コンパイラはこれを解決することができます。関数とグローバル定数も同様に宣言できます。

const PF: Pointer = @MyFunction;

文字列リテラルは、グローバル定数として割り当てられるので、PChar 定数を文字列リテラルで初期化することができます。

const WarningStr: PChar = 'Warning!';

書き込み可能な型付き定数

Object Pascal では、コンパイラ指令 {$J+} または 書き込み可能な型付き定数(Object Pascal){$WRITEABLECONST ON} を設定した場合、型付き定数を変更することができます。

$J+ を設定した場合は、代入文を使用して、型付き定数の値を、その定数があたかも初期化済み変数であるかのように変更できます。次に示すのはその例です。

{$J+}
const
  foo: Integer = 12;
begin
  foo := 14;
end.

書き込み可能な型付き定数と初期化済み変数の違いは次のとおりです。

  • 書き込み可能な型付き定数は、手続き、関数、メソッドにグローバルにもローカルにも出現可能です。
  • 初期化済み変数はグローバル宣言としてのみ使用可能です。
  • 初期化済み変数を手続き内やメソッド内で使用しようとすると、コンパイル時にエラーが発生します。

関連項目