如何模拟Delphi records中的位域
Posted marklove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何模拟Delphi records中的位域相关的知识,希望对你有一定的参考价值。
展开查看·Delphi <-> C++ 基本语法对照表
http://blog.qdac.cc/?p=925 一、标志符命名:两个基本一样,除了保留的关键字,C/C++区分大小写外,剩下的基本一样。一般来说你可以用Delphi的习惯,但注意大小写就好。 二、运算符: 数学运算符:+、-、*是一样的,除在C++里就是一个/,不分div和/,两个整数直接就是相当于div,任意一个是浮点数就是浮点数。 比较操作符:这个C/C++的不等于是!=,而Delphi是<> 位运算符(C++ => Delphi,下同):位与(& => and)、位或(| => or)、位非(~ => not)、异或(^ => xor),左移(变量<<位数 =>变量 shl 位数)、右移(变量>>位数 => 变量 shr 位数) 逻辑运算符:与(&& => and)、或(|| => or)、非(! => not) 地址运算符:& => @ 成员运算符:Delphi均为“.”,C++中指针实例的成员用 -> ,非指针实例的成员用“.”。 指针内容操作符:*指针 => 指针^ 自运算符:变量++ =>Inc(变量),++整型变量 => 无,变量– => Dec(变量),变量+=值 => 变量:=变量+值,变量*=值 =>变量:=变量*值,依次类推,Delphi剩下的都没有 【注】在C++中,&同时被当作引用符号,如:int &a=b ,此时访问a的内容和访问b的内容是等价的。 三、语句 语句都是以“;”结束,复合语句在C++中是用大括号包含在一起,Delphi是begin/end,对应关系: { => begin } => end 四、变量声明 C++中变量声明的位置不必一定在开始,但C的话规矩就和Delphi一样了。格式: 类型 变量名; => var 变量名:类型 常量的C++和Delphi一样都是用const修饰,同样,C++的变量和常量定义你可以随便在什么地方。 五、流程控制 条件判断:if(条件)/else if(条件)/else =>if 条件 then/else if 条件 then/else 分支选择:switch(变量){ case 值:语句;default:默认处理语句;}=>case 变量 of 值:语句 else 默认语句 end while循环:while(条件)语句; => while 条件 do 语句; repeat循环:do 语句 while(条件); => repeat 语句 until 条件;注意两个条件是相反的,一个是成立时继续,一个是直到不成立 for循环:for(初始化语句;结束条件;额外控制) 语句 => for 循环变量:=初始值 to/downto 目标值 do 语句 六、函数 C++不区分过程和函数,过程对于C++而言只是返回值为void的函数,Delphi中函数是要求有返回值,过程没有返回值,对应格式如下: 函数: 返回值类型 [修饰符] 函数名(函数参数){函数代码} => function 函数名(函数参数):返回值类型;[修饰符];begin 函数代码 end; 过程: void [修饰符] 函数名(函数参数){函数代码} => procedure函数名(函数参数):返回值类型;[修饰符];begin 函数代码 end; 【注】 如果函数参数传地址,Delphi的var类型定义,一般翻译成引用,当然也可以翻译成指针。如: procedure Inc1(var x:Integer); begin Inc(x); end;
procedure Inc1(var x:Integer);
begin
Inc(x);
end;
翻译成C++可以是:void __fastcall Inc1(int &x)
{
x++;
}
或
void __fastcall Inc11(int x)
{
(x)++;
}void __fastcall Inc1(int &x)
{
x++;
}
或
void __fastcall Inc11(int x)
{
(x)++;
}
加上__fastcall修饰符是因为Delphi的调用规则默认是fastcall,保持一致。
七、基本类型
C++没有集合类型,所以delphi中的set没有直接对应类型,但C++ Builder对应了一个Set模板类,咱们不说。只说基本类型之间的映射关系:
char => AnsiChar
wchar_t => WideChar
unsigned char => Byte
short => Smallint
unsigned short => Word
int => integer
unsigned int =>Cardinal
long => Longint
unsigned long =>Cardinal
__int64 => Int64
unsigned __int64 =>UInt64
enum 枚举类型名 {枚举值列表 } => type 枚举类型名=(枚举值列表)
struct 结构体类型名{成员定义}=> 结构体类型名=[packed] record 成员定义 end;
class 类型名[: public/protected/private 父类名]=> 类型名=class[(父类名)]
union 联合(共用体)类型名{成员定义} => 类型名=record case 类型 of 值:(成员定义); end;
位域在Delphi中没有对应的定义,只能定义为相应的类型,然后自己去检测标志位。
【注】C++中,结构、类和接口实际上没有什么本质的区别,C++的结构体一样可以有构造和析构函数,一样可以继承和重载函数,如果非要说有区别,那么最大的区别就是C++里结构体默认成员是公开的(public),而类默认是私有的(private),但你可以用完全同样的语法去规定各个成员的可见性。至于接口,C++中本身就是record的别名。
八、引用外部文件include <文件名> =>uses 单元名 或 {$I 文件名}
include “文件名” => uses 单元名 或 {$I 文件名}
九、强制类型转换
(类型)值 => 类型(值)
dynamic_cast<类型>(变量) => 值 as 类型
Delphi的is可以用检查dynamic_cast的值是否为空来代替,另外,C++还有一堆static_cast/reinterpret_cast/const_cast等转换方式,但常用的是上面的方法。
public
property BaseMid: Byte read FBaseMid write FBaseMid;
property &Type: Byte read GetType write SetType; // 0..31
property Dpl: Byte read GetDpl write SetDbl; // 0..3
property Pres: Boolean index 128 read GetBit1 write SetBit1;
property LimitHi: Byte read GetLimitHi write SetLimitHi; // 0..15
property Sys: Boolean index 16 read GetBit2 write SetBit2;
property Reserved0: Boolean index 32 read GetBit2 write SetBit2;
property DefaultBig: Boolean index 64 read GetBit2 write SetBit2;
property Granularity: Boolean index 128 read GetBit2 write SetBit2;
property BaseHi: Byte read FBaseHi write FBaseHi;
end;
function TBits.GetType: Byte;
begin
Result := (FTypeDplPres shr 3) and $1F;
end;
procedure TBits.SetType(const AType: Byte);
begin
FTypeDplPres := (FTypeDplPres and $07) + ((AType and $1F) shr 3);
end;
function TBits.GetDpl: Byte;
begin
Result := (FTypeDplPres and $06) shr 1;
end;
procedure TBits.SetDbl(const ADpl: Byte);
begin
FTypeDblPres := (FTypeDblPres and $F9) + ((ADpl and $3) shl 1);
end;
function TBits.GetBit1(const AIndex: Integer): Boolean;
begin
Result := FTypeDplPres and AIndex = AIndex;
end;
procedure TBits.SetBit1(const AIndex: Integer; const AValue: Boolean);
begin
if AValue then
FTypeDblPres := FTypeDblPres or AIndex
else
FTypeDblPres := FTypeDblPres and not AIndex;
end;
function TBits.GetLimitHi: Byte;
begin
Result := (FLimitHiSysEa shr 4) and $0F;
end;
procedure TBits.SetLimitHi(const AValue: Byte);
begin
FLimitHiSysEa := (FLimitHiSysEa and $0F) + ((AValue and $0F) shr 4);
end;
function TBits.GetBit2(const AIndex: Integer): Boolean;
begin
Result := FLimitHiSysEa and AIndex = AIndex;
end;
procedure TBits.SetBit2(const AIndex: Integer; const AValue: Boolean);
begin
if AValue then
FLimitHiSysEa := FLimitHiSysEa or AIndex
else
FLimitHiSysEa := FLimitHiSysEa and not AIndex;
end;
以上是关于如何模拟Delphi records中的位域的主要内容,如果未能解决你的问题,请参考以下文章