お世話になります。
(基本的なことでしたら申し訳ありません)
Windows.pas を眺めてたら、以下の記述がありました。
>type
> PLDTEntry = ^TLDTEntry;
> _LDT_ENTRY = record
> LimitLow: Word;
> BaseLow: Word;
> case Integer of
> 0: (
> BaseMid: Byte;
> Flags1: Byte;
> Flags2: Byte;
> BaseHi: Byte);
> 1: (
> Flags: Longint);
> end;
typeの定義全体の意味はいいのですが、
> case Integer of
> 0: (
> BaseMid: Byte;
> Flags1: Byte;
> Flags2: Byte;
> BaseHi: Byte);
> 1: (
> Flags: Longint);
この部分(case Integer of ...)は、どのような動きというか、
なんなのでしょうか?
(実装部でのcase文なら分かるのですが・・・)
ヘルプでrecord型について参照してみてください。
レコードの可変部分というところに説明があります。
Cで言うところの共用体に相当します。
Cのソースのunionをpascalで書くとこうなります
私もこれの理解には長い間苦しみました。
> レコードの可変部分というところに説明があります
Delphi7 では、ヘルプの「目次」で
Delphi言語リファレンス->データ型と変数->構造化型->レコード型 を辿ると見つかります。しかし、これを読んでも腹には落ちませんでした。
スッキリしたのは、TRect の定義をヘルプで見たときです。
さどやま語に翻訳すると
BaseLow: Word; の行までが、「不変部分」とでもいうべきもので、通常の record型と同じ理解でよい。
case Integer of 以降が「可変部分」である。
var
B: Byte;
C: Word;
LDTEntry: _LDT_ENTRY;
begin
LDTENTRY.BaseMid := 4;
と記述すれば、コンパイラは case 0 の場合と判断してコンパイルする。
LDTENTRY.Flags := $FFFFF;
と記述すれば、case 1 の場合とされる。
続いて
B := LDTENTRY.BaseMid; // これは当然セーフ
C := LDTENTRY.Flags;
label1.Caption := IntToHex(C, 8);
とすると、コンパイルはとおるが、C は Word型に切り詰められて $FFFF となる。
_LDT_ENTRY の場合、2種類のみで使い分ければよいので、
_LDT_ENTRY2 = record
LimitLow: Word;
BaseLow: Word;
case Boolean of // Boolean を使用
true: (
BaseMid: Byte;
Flags1: Byte;
Flags2: Byte;
BaseHi: Byte);
false: (
Flags: Longint);
end;
と記述しても同じことである。
3種類以上で使い分けたい場合は、
_LDT_ENTRY = packed record
LimitLow: Word;
BaseLow: Word;
case Integer of
0: (
BaseMid: Byte;
Flags1: Byte;
Flags2: Byte;
BaseHi: Byte);
1: (
Flags: Longint);
2: (....);
.......
n: (.....);
と記述すればよい。
同様に、Case Integer of の Integer 部分は、case文で使用可能な型なら何でも使える。
ツイート | ![]() |