加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 积分真常量的类型是什么?

发布时间:2020-12-15 04:26:36 所属栏目:大数据 来源:网络整理
导读:我很抱歉提出一个非常基本的问题.请考虑以下示例: const c1 = 1; // Is this Byte or ShortInt? c2 = 1234; // Is this Word or Smallint? c3 = 123456; // Is this Cardinal or Integer? 在阅读了这个documentation之后,我可以得出结论,负值被解释为有符号
我很抱歉提出一个非常基本的问题.请考虑以下示例:
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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读