LongInt和Integer的区别,LongWord和Cardinal的区别是什么?

12

在Delphi中,LongInt和Integer有什么区别?LongWord和Cardinal有什么区别?

而且我有时会发现使用DWORD,那是什么意思?

它们在所有Delphi版本中都一致吗?我应该坚持使用哪一个?


1
我相信,向在线文档查询“DWORD”将立即给您一个解释。 - Free Consulting
6个回答

10
简而言之:Longint和Longword是固定大小的整数,前者带符号,后者不带符号,通常都是32位大小。在XE8中,它们的大小取决于平台,但在XE7及更早版本中是固定大小(32位)。
Integer和Cardinal不是固定大小的。它们被称为“通用”整数(不要将其与泛型混淆,泛型是另一回事),即应该在需要整数类型时使用,而不考虑大小。根据版本和平台的不同,Integer和Cardinal的大小可能会有所不同。目前,它们的大小和类型与Longint和Longword相同。
固定大小类型的大小在版本或平台之间不会有所不同。您应该在必须与来自其他来源的代码或数据进行接口的情况下使用这些类型,换句话说,在需要精确的二进制兼容性的情况下使用,例如调用API函数。因此使用了像DWORD等类型。
请注意,当前版本有类型别名,例如Byte或Smallint。它们是Int8,UInt8,Int16,UInt16等等...一直到UInt64。这些名称比“Smallint”(16位带符号)或“Shortint”(8位带符号)更容易记忆。因此,在可能的情况下,请使用Integer和Cardinal,因为这些可能是平台和版本的理想类型。当需要与其他数据进行精确的二进制兼容性时,请使用固定大小的类型,例如Byte,Smallint,Longint或UInt64,只是其中之一。更新:由于存在某些混淆(请参见顶部链接),并且现在不再将Longint和Longword视为固定大小的平台无关类型,而是奇怪的是,Integer和Cardinal被视为固定大小,我越来越倾向于使用(U)IntXX版本,例如UInt16或Int32。一个例外是我使用Byte,我无法想象它的大小会改变(为1)。当然,对于任何需要整数类型但大小不重要的内容,例如循环计数器等,我将使用Integer和Cardinal。

1
整数和基数从过去到现在都没有改变(事实上)。并且在未来也永远不会改变(按设计)。在XE6的最新文档中明确指出,只有两种平台相关的整数类型 - NativeInt和NativeUInt。所有其他整数类型,包括“integer”和“cardinal”,都是平台无关的。 - Andrei Galatyn
1
@Andrei 整数和基数在过去发生了彻底的变化,从D1到D2。 - David Heffernan
2
@AndreiGalatyn,这个问题比较复杂。在64位进程中,32位整数的性能优于64位整数的性能。性能不是原因。NativeIntNativeUInt的目的是获得与指针大小相同的整数类型。就这样。如果在将来的某个世界中,64位整数的性能优于32位整数,那么也许Integer会改变。或者,为了匹配平台内存模型,在64位Mac/Linux上,Longint将是64位的。我认为你无法预知未来。 - David Heffernan
2
@Andrei:你可能看不到任何原因,但是在同一平台上,Integer通常与其他语言中的整数大小相同。如果特定(新)平台上的整数大小不是32位,则Integer的大小也可能会发生变化。这就是通用整数类型(如Integer)、固定大小整数类型(如Longint)和指针大小整数类型(如NativeInt)之间的区别。 - Rudy Velthuis
1
@Andrei:NativeInt 是指针大小,因此您可以在其中存储指针。如果指针和整数具有不同的大小(在几个平台上是这样),则应该是指针大小,而不是整数大小。大多数 64 位平台上的整数大小为 32 位,但在 Win64 中,NativeInt 为 64 位,因为指针为 64 位。 - Rudy Velthuis
显示剩余21条评论

3
  • Delphi中的Integer是底层平台的C++int
  • Delphi中的LongInt是底层平台的C++ long int
  • Delphi中的Cardinal是底层平台的C++ unsigned int
  • Delphi中的LongWord是底层平台的C++ unsigned long int

这四个类型都是与平台相关的。

在撰写本文时,所有受支持的平台上,IntegerCardinal都是32位类型。尽管这些类型是与平台相关的,但在所有受支持的平台上,它们恰好是相同大小的类型。

在64位*nix平台上,LongIntLongWord是64位类型。在本文撰写时,对于所有其他受支持的平台,这些类型都是32位类型。

关键点是这些类型都是与平台相关的。

DWORD是Windows API使用的类型别名,只有在使用该API时才使用它。

应该使用Integer还是LongInt?这取决于您的使用。一般而言,对于交互操作,请使用与C++代码匹配的任一类型。否则,在大多数情况下,Integer是适用的。当然,这只是对您一般性问题的一般回答。


显然并不完全正确:在http://docwiki.embarcadero.com/RADStudio/Berlin/en/Simple_Types_(Delphi)上,整数(Integer)和无符号整数(Cardinal)现在被列为**平台无关**(即固定大小)类型。 - Rudy Velthuis
@RudyVelthuis 这可能是一份文档错误。如果不是的话,那么它会使得交互变得有些棘手。我的意思是,如果没有与“int”相对应的类型,我们该如何翻译C头文件呢? - David Heffernan
我知道历史。但是已经决定那不再重要了。而且,所谓的平台无关性是指它在不同平台上保持大小独立。但在Win 3.x上是16位,就在昨天,我看了Delphi 1 OP语言指南,其中Integer和Cardinal被列为通用,即平台相关,而固定大小类型被列为基本。在D1 OPLG中,他们甚至提到了Integer和Cardinal在32位平台上的大小和值范围! - Rudy Velthuis
我理解它的意思是,目前在所有平台上,Integer和Cardinal是相同的。但我不认为这是永久不变的保证。我们看到,在64位posix平台得到支持,并且longxxx在那里变成了64位时,情况并非如此。 - David Heffernan
@rudy,我不太在意你的想法。你对此有自己的看法,就像你对winapi缓冲区长度一样。 - David Heffernan
显示剩余8条评论

1

该文档说明Longint是一个32位有符号整数。这可能会让某些人误以为Longint是一个32位有符号整数,但实际上它是一个64位有符号整数。来源:Delphi文档。很令人困惑 - 我知道;因此才有了这个问题。 - Ian Boyd
1
在 Windows 32 平台上,LongInt 是 32 位有符号整数,在 64 位 Windows 平台上也是如此,但在 64 位 iOS 平台上是 64 位。这在最新的 Delphi 文档 中仍然成立。此外请注意,在我的回答中,我链接了 Delphi XE5 文档,该文档在发布问题后仅两个月就发布了 Delphi XE6。但现在您正在参考 Delphi XE8 文档,这是一份当时还未出现的 Delphi 版本的文档。 - SilverWarior
无论如何,如果您正在尝试使用最新信息更新您的答案,您应该提供到最新Delphi版本的文档链接,目前为Delphi 10.4 Sydney。 - SilverWarior

1

简短版本

| Type        | 16-bit platform | 32-bit platform | 64-bit platform  |
|-------------|-----------------|---------------- |------------------|
| Integer     | 16-bit signed   |            32-bit signed           | "generic type"
| Cardinal    | 16-bit unsigned |            32-bit unsigned         | "generic type"

| Longint     | 32-bit signed   | 32-bit signed   | 64-bit signed    | "fundamental type"
| Longword    | n/a             | 32-bit unsigned | 64-bit unsigned  | "fundamental type"
| Int64       | n/a             | 64-bit signed   | 64-bit signed    | "fundamental type"
| UInt64      | n/a             | 64-bit unsigned | 64-bit unsigned  | "fundamental type"
| Int32       | n/a             |            32-bit signed           |  
| UInt32      | n/a             |            32-bit unsigned         | 

| NativeInt   | n/a             | 32-bit signed   | 64-bit signed    |
| NativeUInt  | n/a             | 32-bit unsigned | 64-bit unsigned  |

| FixedInt    | n/a             |            32-bit signed           |
| FixedUInt   | n/a             |            32-bit unsigned         |

长答案

我们都知道他们应该做什么:

| Type        | 16-bit platform | 32-bit platform | 64-bit platform  |
|-------------|-----------------|---------------- |------------------|
| Integer     | 16-bit signed   | 32-bit signed   | 64-bit signed    | "generic type"
| Cardinal    | 16-bit unsigned | 32-bit unsigned | 64-bit unsigned  | "generic type"

| SmallInt    |                   16-bit signed                      | "fundamental type"
| Word        |                   16-bit unsigned                    | "fundamental type"
| Longint     |                   32-bit signed                      | "fundamental type"
| Longword    |                   32-bit unsigned                    | "fundamental type"
| Int64       |                   64-bit signed                      | "fundamental type"
| UInt64      |                   64-bit unsigned                    | "fundamental type"
  • 基本类型不会改变
  • 通用类型(别名)可能会改变

但他们并没有这样做,所以我们现在的情况就是这样。

可以预期,Int32 一直是 有符号的32位整数;但是保证曾经被打破过。

额外阅读

额外聊天

来自 Delphi 5 帮助:

Integer types


An integer type represents a subset of the whole numbers. The generic integer types are Integer and Cardinal; use these whenever possible, since they result in the best performance for the underlying CPU and operating system. The table below gives their ranges and storage formats for the current 32-bit Object Pascal compiler.

Type      Range                    Format
--------  -----------------------  ---------------
Integer   –2147483648..2147483647  signed 32-bit
Cardinal  0..4294967295            unsigned 32-bit

Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword.

Type      Range                    Format
--------  -----------------------  ----------------
Shortint  –128..127                signed 8-bit
Smallint  –32768..32767            signed 16-bit
Longint   –2147483648..2147483647  signed 32-bit
Int64     –2^63..2^63–1            signed 64-bit
Byte      0..255                   unsigned 8-bit
Word      0..65535                 unsigned 16-bit
Longword  0..4294967295            unsigned 32-bit

In general, arithmetic operations on integers return a value of type Integer—which, in its current implementation, is equivalent to the 32-bit Longint. Operations return a value of type Int64 only when performed on an Int64 operand.

请注意"在当前实现中,等同于Longint"。当时的想法是Integer会改变;他们并没有意识到Longint才会改变。

来自Delphi 1用户指南:

数据类型
Object Pascal 语言内置了几种数据类型。您可以创建任何这些预定义类型的变量。以下表格列出了预定义数据类型:
Table 5.1 Object Pascal 预定义数据类型
- Integer:没有小数部分的数字,范围为 -32768 到 32767。需要两个字节的内存。 - Shortint:没有小数部分的数字,范围为 -128 到 127。只需要一个字节的内存。 - Longint:没有小数部分的数字,范围为 -2147483647 到 2147483647。需要四个字节的内存。 - Byte:没有小数部分的数字,范围为 0 到 255。需要一个字节的内存。 - Word:没有小数部分的数字,范围为 0 到 65535。需要两个字节的内存。

Integer Types ================

An integer type represents a subset of the integral numbers.

Integer types can be platform-dependent and platform-independent.

Platform-Dependent Integer Types


The platform-dependent integer types are transformed to fit the bit size of the current compiler platform. The platform-dependent integer types are NativeInt and NativeUInt. Using these types whenever possible, since they result in the best performance for the underlying CPU and operating system, is desirable. The following table illustrates their ranges and storage formats for the Delphi compiler.

Platform-dependent integer types

Type         Range                    Format                                  Alias  
-----------  -----------------------  --------------------------------------  ------------
NativeInt    -2147483648..2147483647  Signed 32-bit on 32-bit platforms or    Integer
             -2^63..2^63-1            Signed 64-bit on 64-bit platforms       Int64 
NativeUInt   0..4294967295            Unsigned 32-bit on 32-bit platforms or  Cardinal
             0..2^64-1                Unsigned 64-bit on 64-bit platforms     UInt64

Platform-Independent Integer Types

Platform-independent integer types always have the same size, regardless of what platform you use. Platform-independent integer types include ShortInt, SmallInt, LongInt, Integer, Int64, Byte, Word, LongWord, Cardinal, and UInt64.

Platform-independent integer types

Type         Range                    Format           Alias  
-----------  -----------------------  ---------------  ------
ShortInt     -128..127                Signed 8-bit     Int8 
SmallInt     -32768..32767            Signed 16-bit    Int16 
LongInt      -2147483648..2147483647  Signed 32-bit    Int32 
Integer      -2147483648..2147483647  Signed 32-bit    Int32 
Int64        -2^63..2^63-1            Signed 64-bit    
Byte         0..255                   Unsigned 8-bit   UInt8 
Word         0..65535                 Unsigned 16-bit  UInt16 
LongWord     0..4294967295            Unsigned 32-bit  UInt32 
Cardinal     0..4294967295            Unsigned 32-bit  UInt32 
UInt64       0..2^64-1                Unsigned 64-bit 
注意到 IntegerCardinal 被记录为平台相关了吗?还注意到 LongIntLongWord 被记录为平台无关了吗?

-1
以前有 基本 整数类型(不应该改变)和 通用类型,理论上可以因不同的平台而异,尽管整数类型实际上从未改变。现在,在 XE6 的文档中,整数类型有一个更加逻辑、简单和清晰的定义,只有两种依赖于平台的整数类型:
NativeInt
NativeUInt

所有其他整数类型都是与平台无关的:

ShortInt 
SmallInt 
LongInt 
Integer 
Int64 
Byte 
Word 
LongWord 
Cardinal 
UInt64 

建议详细阅读帮助文档中的“简单类型”部分,以获取更多信息。

Integer在完全错误的列表中。您误解了通用和基本类型的概念。 - Free Consulting
@Free 你觉得这个有错误的话,能否解释一下原因? - Andrei Galatyn
@Free,我在回答中提到了这一点——最新的Emb文档中已经没有“通用”和“基本”的整数类型。只有平台相关和平台无关的类型。而“integer”被定义为平台无关的类型。即使是针对x32/x64,它也是相同的类型。那么你的意思是什么呢? - Andrei Galatyn
但是你在回答中提到了通用概念。从预先混乱的文档版本中复制粘贴:Delphi 32位实现的通用整数类型:Integer Cardinal 通用类型背后的[精彩]想法是当您不担心实现时使用它们(例如:循环计数器)。 - Free Consulting
1
@免费咨询 64位Windows是IL32P64。他们还能做什么呢?他们遵循了这个平台。没有任何故障。他们在Win64上的执行非常出色。我作为一个在他们的Win64编译器上交付产品的人,可以说非常满意。 - David Heffernan
显示剩余4条评论

-1

2
DWORD是Windows数据类型,而不是别名... - TLama
@TLama 在 Delphi 中,DWORD 被定义为 Cardinal 的别名。 - David Heffernan
2
@David,虽然它被定义为这样,但如果有人问你“有时我发现使用DWORD,那是什么?”你会回答“它是Cardinal的别名”吗?我不会。它最初是Windows数据类型,用于Windows API调用。我认为它只应该为此目的声明。 - TLama
@TLama 说得对。语义上来讲,它是一个32位无符号类型。 - David Heffernan
DWORD在Windows之前就存在了。它由2个WORD组成,而当时的一个WORD是2个BYTE。全部都是无符号的。只是说一下。 - David Schwartz
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接