将整数转换为布尔值的打包记录的函数?
Function to convert Integer to Packed Record of booleans?
尝试将整数转换为 32 个布尔值的压缩记录。
TUserRightsRecord = packed record
r1:boolean;
.
.
end;
但是,我找不到将变量转换为打包记录的函数,因为直接赋值不起作用。
- 什么函数将变量(或至少 Integer)转换为相同大小的打包记录?
用 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) = 4
而 SizeOf(<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
尝试将整数转换为 32 个布尔值的压缩记录。
TUserRightsRecord = packed record
r1:boolean;
.
.
end;
但是,我找不到将变量转换为打包记录的函数,因为直接赋值不起作用。
- 什么函数将变量(或至少 Integer)转换为相同大小的打包记录?
用 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) = 4
而 SizeOf(<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