将整数转换为布尔值的打包记录的函数?

Function to convert Integer to Packed Record of booleans?

尝试将整数转换为 32 个布尔值的压缩记录。

 TUserRightsRecord = packed record
    r1:boolean;
    .
    .

 end;

但是,我找不到将变量转换为打包记录的函数,因为直接赋值不起作用。

用 longbool 替换 boolean 可能就足够了

program Project1;
{$APPTYPE CONSOLE}
{$R *.res}

uses
 System.SysUtils;
var
  i: integer;
begin
 try
   i := Sizeof(boolean);
   writeln('Sizeof(boolean): ', i);

   i := Sizeof(LongBool);
   writeln('Sizeof(LongBool): ', i);

   readln(i);

 except
   on E: Exception do
     Writeln(E.ClassName, ': ', E.Message);
 end;
end.

否则您可能必须将自己的数据类型定义为记录。这里你必须注意你的数据类型“SizeOf”的内存大小。这里有一个例子:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TConvert=packed record
  public
    function ToString: string;
  public
    //Redefined memory. Each field has the same start address.
    case integer of
      0: (b: boolean);
      1: (G: LongBool);
      2: (i: integer);
      3: (data: array[0..3]of byte);
  end;

function TConvert.ToString: string;
begin
  //Low is left !!!
  Result := Format('[%.2x|%.2x|%.2x|%.2x]', [data[0], data[1], data[2], data[3]]);
end;

var
  i: integer;
  r: TConvert;
begin
  try
    i := Sizeof(TConvert);
    writeln('Sizeof(TConvert): ', i);

r.b := True;
writeln('boolean(true): ', r.ToString, ' ',BoolToStr(r.G, true));
r.G := false;
writeln('LongBool(false): ', r.ToString, ' ',BoolToStr(r.G, true));
r.G := True;
writeln('LongBool(true): ', r.ToString, ' ',BoolToStr(r.G, true));
r.i := 1;
writeln('LongBool(i=1): ', r.ToString, ' ',BoolToStr(r.G, true));


readln(i);

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Trying the convert an Integer to a Packed Record of 32 booleans.

请注意 SizeOf(Integer) = 4SizeOf(<packed record of 32 booleans>) = 32 因为 SizeOf(Boolean) = 1 (1 字节 = 8 位)。您似乎认为 Boolean 是一个位;它不是。

但是,如果是这种情况,您可以简单地将整数转换为这样的记录。

(但是当然可以编写一个将整数“转换”为 32 个布尔值记录的函数。)


在整数中使用位的标准方法是使用按位运算符:

const
  HasScreen = 1;
  HasSound = 2;
  HasKeyboard = 4;
  HasMouse = 8;
  HasInternet = 16;

var
  ComputerProperties: Integer;

begin
  // Test a bit
  if ComputerProperties and HasInternet = 0 then
    ShowMessage('You need an Internet connection.');

  // Set a bit
  Computer := Computer or HasInternet;

  // Clear a bit
  Computer := Computer and not HasInternet;

在Delphi中,使用sets更为惯用:

type
  TComputerFeature = (cfScreen, cfSound, cfKeyboard, cfMouse, cfInternet);
  TComputerFeatures = set of TComputerFeature;

var
  Features: TComputerFeatures;

begin
  Features := [cfScreen, cfKeyboard];
  if not (cfInternet in Features) then
    ShowMessage('You need an Internet connection.');
  Include(Features, cfInternet);
  Exclude(Features, cfInternet);
end;

但是,您可以使用高级记录轻松模拟您的原始设计方法:

type
  TBit32 = type Integer;
  TBit32Helper = record helper for TBit32
  strict private
    function GetBit(Index: Integer): Boolean;
    procedure SetBit(Index: Integer; const Value: Boolean);
  public
    property Bit[Index: Integer]: Boolean read GetBit write SetBit;
  end;

function TBit32Helper.GetBit(Index: Integer): Boolean;
begin
  Result := (Self shr Index) and 1 <> 0;
end;

procedure TBit32Helper.SetBit(Index: Integer; const Value: Boolean);
begin
  if Value then
    Self := Self or (1 shl Index)
  else
    Self := Self and not (1 shl Index);
end;

begin
  var x: Integer := 123;
  Writeln(TBit32(x).Bit[4]); // read
  TBit32(x).Bit[6] := False; // write