集合型変数の内部構造が知りたい/数値として処理したい。
|
集合型の変数は、フラッグの集まりです。
例えば、
type
TDbit = 0..25;
TDbits = set of TDbit;
と定義し、
Var D:TDbit;
D := [1,3,4,6]; の場合
内部的には,00000000 00000000 00000000 01011010B
とビット表現されています ~~~~~~~~~
したがって、Integer(D)とキャスト可能で、この値は90です
集合で使うバイト数は次の式で計算します。
ByteSize = (Max div 8) - (Min div 8) + 1
※ 最大255要素ですから、最大32バイト
Min と Max は集合の基本型の下限と上限です。
特定の要素 E が何バイト目かは次の式でわかります。
ByteNumber = (E div 8) - (Min div 8)
そのバイト内で何ビット目かは次の式でわかります。
BitNumber = E mod 8
※ E は要素の順序値を表します。
GetLogicalDrives関数は、 現在利用可能なディスクドライブを表すビットマスクを返しますので、これで、試してみましょう。返り値のビット位置0 (最下位ビット) はドライブAに対応します。
バイトサイズ → (25 div 8) - (0 div 8) + 1 = 4
で、4バイト、DWord型やLongint型が使えます。
TDBitsの最小値は → 0
0 mod 8 → 0 ですから、そのまま対応できます
procedure TForm1.Button1Click(Sender: TObject);
var
d: TDbit;
drvs: TDbits;
DName:string;
begin
ListBox1.Items.Clear;
// マシンのドライブをえる
DWORD(drvs) := GetLogicalDrives;
for d := Low(TDbit) to High(TDbit) do
begin
if d in drvs then
begin
DName := Chr(Integer('A') + d) + ':\';
// ドライブタイプをえる
case GetDriveType(PChar(Char(Ord('A')+d)+':\')) of
DRIVE_REMOVABLE: DName := DName + 'リマーブルデスク';
DRIVE_FIXED: DName := DName + 'ハードデスク';
DRIVE_REMOTE: DName := DName + 'ネットワークデスク';
DRIVE_CDROM: DName := DName + 'CDROMデスク';
DRIVE_RAMDISK: DName := DName + 'ラムデスク';
end;
ListBox1.Items.Add(DName);
end;
end;
end;
次に、
Type
TDrive = 'A'..'Z';
TDrives = Set of TDrive; を使えばどうでしょうか。
TDrivesの最小値は → 'A' 順序値 65
65 mod 8 → 1 ですから、
返り値の0ビットは、TDravesの1ビット目に対応します。
procedure TForm1.Button1Click(Sender: TObject);
var
d: TDrive;
drvs: TDrives;
DName:string;
begin
ListBox1.Items.Clear;
// マシンのドライブをえる−−左に1ビットシフトする
DWORD(drvs) := GetLogicalDrives shl 1;
for d := Low(TDrive) to High(TDrive) do
begin
if d in drvs then
begin
DName := Char(d) + ':\';
// ドライブタイプをえる
case GetDriveType(PChar(d +':\')) of
DRIVE_REMOVABLE: DName := DName + 'リマーブルデスク';
DRIVE_FIXED: DName := DName + 'ハードデスク';
DRIVE_REMOTE: DName := DName + 'ネットワークデスク';
DRIVE_CDROM: DName := DName + 'CDROMデスク';
DRIVE_RAMDISK: DName := DName + 'ラムデスク';
end;
ListBox1.Items.Add(DName);
end;
end;
end;
集合型を内部表現で使うのは、注意が必要です。
なるべく集合型として使いましょう。
なお、集合型の演算子として +,*,-,IN が定義されていますので、
not は、 全定義 - 値
xor は、 和集合 - 積集合で代用できます。
要素数は、4バイトまでの集合なら以下のようなぐあいですか?
function GetElements(Drvs: TDrives):DWORD;
var
i:TDrive;
begin
result := 0;
for i := Low(TDrive) to High(TDrive) do
begin
inc(result,DWORD(Drvs) and 1);
DWORD(Drvs) := DWORD(drvs) shr 1;
end;
end;
*リマーブルデスクって・・・(ぷ |
|