gpt4 book ai didi

delphi - 整数真常数的类型是什么?

转载 作者:行者123 更新时间:2023-12-03 14:57:30 24 4
gpt4 key购买 nike

很抱歉问了一个非常基本的问题。考虑以下示例:

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.

输出为:

Int8UInt8Int16UInt16Int32UInt32Int64UInt64Int32UInt16UInt8

Let's have a look at another program:

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

So, by my empirical analysis, the compiler looks at the value of an integral literal, and determines its type by finding the first type in the following list which can represent the value:

  • Int8
  • UInt8
  • Int16
  • UInt16
  • Int32
  • UInt32
  • Int64
  • UInt64

This rule can be overridden by specifying the type using the typecast syntax. For instance, to declare an Int32 with value 0 you would write Int32(0).


Now let us apply that rule to the concrete example that you give in the question, namely 123456. According to the rules above, the first type in the list which can represent this value is Int32. Also known as Integer.

Now, because this is an unsigned type, you might expect that a comparison against an unsigned UInt32 variable will result in warning W1023, comparing signed and unsigned types. But that is not the case. The compiler recognises that 123456 is a positive value and that we are comparing two positive values. On the other hand, the warning is emitted with -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

关于delphi - 整数真常数的类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32160057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com