我很抱歉提出一个非常基本的问题.请考虑以下示例:
const c1 = 1; // Is this Byte or ShortInt? c2 = 1234; // Is this Word or Smallint? c3 = 123456; // Is this Cardinal or Integer?
在阅读了这个documentation之后,我可以得出结论,负值被解释为有符号,而正值被解释为无符号.但是,例如123456(根据文档将被解释为Cardinal)也可以在Integer的上下文中使用,我的意思是它用于在计算中使用常量的Integer变量.因此,常量保证永远是Cardinal,以便对Integer进行类型转换吗?
解决方法
documentation(XE8是我写的最新版本)告诉你真正的常量有一个类型.但是,在指定实际类型时,文档会产生误导.当我说出误导时,我有些善意.
如果您阅读此官方documentation,那么您会倾向于认为无符号类型比签名类型更受欢迎.但是这个程序表明情况并非如此:
program SO32160057_overloads; {$APPTYPE CONSOLE} procedure foo(value: UInt8); overload; begin Writeln('UInt8'); end; procedure foo(value: UInt16); overload; begin Writeln('UInt16'); end; procedure foo(value: UInt32); overload; begin Writeln('UInt32'); end; procedure foo(value: UInt64); overload; begin Writeln('UInt64'); end; procedure foo(value: Int8); overload; begin Writeln('Int8'); end; procedure foo(value: Int16); overload; begin Writeln('Int16'); end; procedure foo(value: Int32); overload; begin Writeln('Int32'); end; procedure foo(value: Int64); overload; begin Writeln('Int64'); end; const ZeroInt32 = Int32(0); ZeroUInt16 = UInt16(0); begin foo(127); foo(128); foo(32767); foo(32768); foo(2147483647); foo(2147483648); foo(9223372036854775807); foo(9223372036854775808); foo(ZeroInt32); foo(ZeroUInt16); foo(UInt8(0)); end.
输出是:
Int8 UInt8 Int16 UInt16 Int32 UInt32 Int64 UInt64 Int32 UInt16 UInt8
我们来看看另一个程序:
program SO32160057_comparisons; var Int8var: Int8 = 0; Int16var: Int16 = 0; Int32var: Int32 = 0; begin if Int8var < 127 then ; if Int8var < 128 then ; // line 10 if Int8var < Int16(128) then ; // line 11 if Int16var < 32767 then ; if Int16var < 32768 then ; // line 13 if Int16var < Int32(32768) then ; // line 14 if Int32var < 2147483647 then ; if Int32var < 2147483648 then ; // line 16 if Int32var < Int64(2147483648) then ; end.
编译器发出以下警告:
(10): W1022 Comparison always evaluates to True (10): W1023 Comparing signed and unsigned types - widened both operands (11): W1022 Comparison always evaluates to True (13): W1022 Comparison always evaluates to True (13): W1023 Comparing signed and unsigned types - widened both operands (14): W1022 Comparison always evaluates to True (16): W1022 Comparison always evaluates to True (16): W1023 Comparing signed and unsigned types - widened both operands
因此,通过我的实证分析,编译器会查看整数文字的值,并通过查找以下列表中可以表示值的第一个类型来确定其类型:
> Int8
> UInt8
> Int16
> UInt16
> Int32
> UInt32
> Int64
> UInt64
可以使用类型转换语法指定类型来覆盖此规则.例如,要声明值为0的Int32,您将写入Int32(0).
现在让我们将该规则应用于您在问题中给出的具体示例,即123456.根据上面的规则,列表中可以表示此值的第一个类型是Int32.也称为整数.
现在,因为这是一个无符号类型,您可能希望与无符号UInt32变量进行比较将导致警告W1023,比较有符号和无符号类型.但事实并非如此.编译器识别出123456是正值,并且我们正在比较两个正值.另一方面,使用-123456发出警告.
program SO32160057_123456; var UInt32var: UInt32 = 0; begin if UInt32var > 123456 then ; // line 7 if UInt32var > -123456 then ; // line 8 end.
编译器发出以下警告:
(8): W1022 Comparison always evaluates to True (8): W1023 Comparing signed and unsigned types - widened both operands