文档章节

Delphi中的数据类型

天朝八阿哥
 天朝八阿哥
发布于 2017/08/13 14:34
字数 1003
阅读 117
收藏 0

之前一直使用的是Delphi 7,现在准备转向Delphi XE7,据说数据类型上有一些微小的调整,便想亲自验证一下,也顺便加深一下自己对Delphi数据类型的认识,毕竟之前仅仅是在用而从未考虑过类型在内存中的形态。

验证方法很简单,就是在控制台用Sizeof()把相应数据类型的字节数显示出来。源码如下:

program TypeSize;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  Emnu = (one, two, three, four);

  Range1 = $0..$FF;

  Range2 = $0..$FFFF;

  Range3 = $0..$FFFFFFFF;

  arr1 = array of Byte;

  arr2 = array[0..9] of Byte;

  arr3 = array[0..9] of Integer;

  rcd1 = record
  end;

  rcd2 = record
    b: Byte;
  end;

  rcd3 = record
    i: Integer;
  end;

  rcd4 = record
    i: Integer;
    j: Integer;
  end;

  rcd5 = record
    b: Byte;
    i: Integer;
  end;

  rcd6 = record
    r: Real;
  end;

  rcd7 = record
    r: Real;
    i: Integer;
  end;

  obj1 = object
  end;

  obj2 = object
    c: Char;
  end;

  obj3 = object
    i: Integer;
    o: obj2;
  end;

begin
  Writeln('   Type     | Bytes');
  Writeln('--------------------------------');
  Writeln('AnsiChar    = ', SizeOf(AnsiChar));
  Writeln('WideChar    = ', SizeOf(WideChar));
  Writeln('Char        = ', SizeOf(Char));
  Writeln('Byte        = ', SizeOf(Byte));
  Writeln('ShortInt    = ', SizeOf(ShortInt));
  Writeln('SmallInt    = ', SizeOf(SmallInt));
  Writeln('LongInt     = ', SizeOf(LongInt));
  Writeln('Int64       = ', SizeOf(Int64));
  Writeln('Byte        = ', SizeOf(Byte));
  Writeln('Word        = ', SizeOf(Word));
  Writeln('LongWord    = ', SizeOf(LongWord));
  Writeln('Integer     = ', SizeOf(Integer));
  Writeln('Cardinal    = ', SizeOf(Cardinal));
  Writeln('Boolean     = ', SizeOf(Boolean));
  Writeln('ByteBool    = ', SizeOf(ByteBool));
  Writeln('WordBool    = ', SizeOf(WordBool));
  Writeln('LongBool    = ', SizeOf(LongBool));
  Writeln('Single      = ', SizeOf(Single));
  Writeln('Real48      = ', SizeOf(Real48));
  Writeln('Double      = ', SizeOf(Double));
  Writeln('Extended    = ', SizeOf(Extended));
  Writeln('Comp        = ', SizeOf(Comp));
  Writeln('Currency    = ', SizeOf(Currency));
  Writeln('Real        = ', SizeOf(Real));
  Writeln('ShortString = ', SizeOf(ShortString));
  Writeln('AnsiString  = ', SizeOf(AnsiString));
  Writeln('WideString  = ', SizeOf(WideString));
  Writeln('String      = ', SizeOf(string));
  Writeln('Variant     = ', SizeOf(Variant));
  Writeln('Pointer     = ', SizeOf(Pointer));
  Writeln('--------------------------------');
  Writeln('Emnu        = ', SizeOf(Emnu));
  Writeln('Range(0,FF)       = ', SizeOf(Range1));
  Writeln('Range(0,FFFF)     = ', SizeOf(Range2));
  Writeln('Range(0,FFFFFFFF) = ', SizeOf(Range3));
  Writeln('Array()           = ', SizeOf(arr1));
  Writeln('Array(10)Byte     = ', SizeOf(arr2));
  Writeln('Array(10)Int      = ', SizeOf(arr3));
  Writeln('Record()                   = ', SizeOf(rcd1));
  Writeln('Record(1 byte)             = ', SizeOf(rcd2));
  Writeln('Record(1 int)              = ', SizeOf(rcd3));
  Writeln('Record(2 int)              = ', SizeOf(rcd4));
  Writeln('Record(1 byte, 1 int)      = ', SizeOf(rcd5));
  Writeln('Record(1 real)             = ', SizeOf(rcd6));
  Writeln('Record(1 real, 1 int)      = ', SizeOf(rcd7));
  Writeln('Object()                   = ', SizeOf(obj1));
  Writeln('Object(1 char)             = ', SizeOf(obj2));
  Writeln('Object(1 int, 1 obj(char)) = ', SizeOf(obj3));
  Readln;
end.

分别用Delphi 7和Delphi XE7编译,运行结果如图:

从运行结果可以看出:

  1. Delphi 7 和 Delphi XE7 数据类型的唯一区别就是默认的字符集发生的变化,Delphi 7 中 Char = AnsiChar,Delphi XE7 中Char = WideChar,即 Delphi 7 默认使用 ANSI 编码,Delphi XE7 默认使用 Unicode 编码。相应的,Delphi XE7 中 String = WideString,PChar = PWideChar。
  2. AnsiString、WideString、String 和 Pointer 一样占用 4B 的空间,说明,字符串类型的本质其实就是指针。由于 Delphi 对字符封闭得很好,使用起来感觉和整型、浮点型等没有什么差别,但毕竟还是不一样的,这是需要注意的(有关情况我会在另一篇中详细说明)。
  3. 枚举类型4个元素占1B,其它数量时也是1B,说明枚举类型实际存储的是元素的索引,或者说枚举类型的元素实际是对应索引值的一个别名。至于超过256个元素的情况未进行测试,即枚举类型元素上限未测。
  4. 子界类型与枚举类型比较类似,当元素个数少于256时用1B存储,超过256个时用2B,2B不够时用4B(没有3B的情况),以此推测,4B不够时将用8B、16B等。
  5. 静态数组占用的是连续的内存区域,其大小为数组元素大小的总合;动态数组在未指定数组大小时只有4B,说明动态数组的本质也是指针(有关细节会同字符串一同说明)。
  6. 记录类型的大小一般来说是其元素类型的大小*元素的个数,无元素时0B;如果元素类型不一致,元素类型统一按较大的类型的大小进行存储(猜想是为了方便寻址,拿空间换时间,提高运行速度)。
  7. Object类型是Delphi较早的一种类型,与记录类型很类似,不同的是其占用空间的大小为其元素大小的总合。估计Object类型就是记录类型的前身,而在记录类型出现后也依然没有消亡,想必仅仅是为了兼容古老的程序吧。

© 著作权归作者所有

天朝八阿哥

天朝八阿哥

粉丝 1
博文 23
码字总数 17659
作品 0
郑州
程序员
私信 提问
UniDAC使用教程(四):数据类型映射

下载UniDAC最新版本 Universal Data Access Components (UniDAC)是一款通用数据库访问组件,提供了多个数据库的直接访问,如针对Windows的Delphi, C++Builder, Lazarus (以及 Free Pascal) ,...

电池盒
01/31
14
0
怎样在DELPHI中使用API函数

实际上,在DELPHI中调用WIN32API函数与在C或C++中调用WIN32 API函数没有大的区别。DELPHI中将C或C++中引用的WINDOWS.H头文件改写为WINDOWS.PAS单元,使WINDOWSAPI函数的定义符合PASCAL语法。...

金笛子
2015/12/02
27
0
[转] Java中调用Delphi编写的DLL

有些时候,要写一些程序,在 JAVA 里面好难实现, 但如果使用其它编程语言却又比较容易时,我们不妨通过 JNI 来让不同语言的程序共同完成. JNI 的教程, 网上 C 的比较多,Java 也提供了 javah.ex...

鉴客
2010/10/28
2.8K
1
java将blob数据写入到xml中,Delphi TClientDataSet 读取blob失败

我用java把mysql数据写入到xml中,delphi TClientDataSet读取xml展示数据,数值、文本类型都能正常显示;blob类型异常 这里的原因应该是java将blob数据写入到xml中,delphi不认,请大神指点,...

liutao7514
2014/10/13
212
0
Java中调用Delphi编写的DLL

有些时候,要写一些程序,在 JAVA 里面好难实现, 但如果使用其它编程语言却又比较容易时,我们不妨通过 JNI 来让不同语言的程序共同完成. JNI 的教程, 网上 C 的比较多,Java 也提供了 javah.ex...

geek_loser
2014/09/26
824
0

没有更多内容

加载失败,请刷新页面

加载更多

Java FOR-EACH循环

FOR-EACH循环使得代码更加的简短,也让代码更加易懂,其实他并没有加入什么新的功能。他的功能完全可以用简单的FOR循环代替。 for-each的用法: int a[] = {1,2,3,4,5,6} for(int s:a){ Syst...

无名氏的程序员
30分钟前
3
0
使用HTML5的History API

本文转载于:专业的前端网站➣使用HTML5的History API   HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL。这个功能很有用,例如通过一段JavaScript代...

前端老手
32分钟前
4
0
JAVA 编写redisUtils工具类,防止高并发获取缓存出现并发问题

import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.BoundHashOperations;import org.springframework.data.redis.core.BoundValueOperations;import org.......

huangkejie
今天
7
0
JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
今天
101
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部