这个问题可能听起来很愚蠢,但我无法理解not
运算符背后的常数整数。我得到以下结果:
not $FF
=> $FF00
not $FFFF
=> $FFFF0000
not $FFFFFFFF
=> $00
not $FFFFFFFFFFFFFFFF
=> $00
前两个值对我来说是错误的。
例如,不对整数操作数
执行按位求反
以后:
not操作的结果与操作数
的类型相同
这与观察到的行为不一致。
完整代码示例:
unit Unit5;
interface
procedure c();
implementation
uses Vcl.Dialogs, System.SysUtils;
procedure Invert(v: ShortInt); overload; begin
ShowMessage('ShortInt $' + v.ToHexString());
end;
procedure Invert(v: SmallInt); overload; begin
ShowMessage('SmallInt $' + v.ToHexString());
end;
procedure Invert(v: Integer); overload;
begin
ShowMessage('Integer $' + v.ToHexString());
end;
procedure c();
const
byteValue = not $FF; // = $FF00
wordValue = not $FFFF; // = $FFFF0000
cardValue = not $FFFFFFFF; // = $00
uint64Value = not $FFFFFFFFFFFFFFFF; // = $00
begin
Invert(byteValue);
Invert(wordValue);
Invert(cardValue);
Invert(uint64Value);
end;
end.
答案 0 :(得分:4)
如果可能存在歧义,编译器可以自由*为真常量选择合适的类型。
在这种情况下,您需要使用值类型转换来帮助解决:
const
byteValue = Byte(not $FF); // => $00 (ShortInt)
wordValue = Word(not $FFFF); // => $00 (ShortInt)
为避免过度混淆,因为您只提供签名的打印输出备选方案:
const
byteValue = ShortInt(not $FF); // => $00 (ShortInt)
wordValue = SmallInt(not $FFFF); // => $0000 (SmallInt)
当没有直接重载过程与序数类型匹配时,可能很难预测编译器选择的过载。
来自Declared_Constants#True_Constants:
声明真常量的语法是:
const identifier = constantExpression
其中identifier是任何有效的标识符,而constantExpression是编译器可以在不执行程序的情况下评估的表达式。
如果constantExpression返回一个序数值,您可以使用值类型转换指定声明的常量的类型。
添加了完整的测试:
program Project110;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
procedure Invert(v: ShortInt); overload; begin
WriteLn('ShortInt $' + v.ToHexString());
end;
procedure Invert(v: SmallInt); overload; begin
WriteLn('SmallInt $' + v.ToHexString());
end;
procedure Invert(v: Integer); overload;
begin
WriteLn('Integer $' + v.ToHexString());
end;
procedure Invert(v: Int64); overload;
begin
WriteLn('Int64 $' + v.ToHexString());
end;
procedure c();
const
byteValue = ShortInt(not $FF); // = ShortInt $00
wordValue = SmallInt(not $FFFF); // = SmallInt $0000
cardValue = Integer(not $FFFFFFFF); // = Integer $00000000
uint64Value = Int64(not $FFFFFFFFFFFFFFFF); // = Int64 $0000000000000000
begin
Invert(byteValue);
Invert(wordValue);
Invert(cardValue);
Invert(uint64Value);
end;
begin
c;
ReadLn;
end.