为什么80%的码农都做不了架构师?>>>   

内存中的数据除了 0 便是 1, 你把它当作图片、字符、数字等等, 那是你的事, 内存只认识 0 和 1.

Win32 系统除了使用硬内存以外, 还可以从硬盘上开辟虚拟内存;

因为 Win32 的内存地址范围在 4 个 G 以内(0..2 32-1), 所以它最多能够给一个应用程序分配 4G 的运行空间; 并且其中的 2G 有系统管理, 实际上程序只有 2G 的自主空间. 还记得有说 String 最大长度是 2G 吗? 就是这个道理.

有 4G 的内存, 就有 4G 个地址, 也就是最多可以有 (1024*1024*1024*4 - 1 = 4294967295) 个内存地址, 这刚好是 Delphi 中 Cardinal 的最大值, 所以 32 位的指针类型追到底都是 Cardinal 类型的一个数字.

一个内存地址是 0..4294967295 之间的一个数字, 你可以通过内存地址读取或写入数据;
一个指针要用来索引或标识内存, 它也是 0..4294967295 之间的一个数字; 它们虽不相同, 但通过指针可以找到实际存储数据的内存地址, 并按指定的类型去读写它.

譬如:


varstr: string;n: Cardinal;pstr: PString;
beginstr := 'ABCDE';n := Cardinal(str); {获取内存地址}pstr := @str;       {现在 pstr 是 str 的指针}{n 与 pstr 的数字结果是(结果是随机的, 知道不一样就行了):}ShowMessage(IntToStr(n));              {4571092}ShowMessage(IntToStr(Cardinal(pstr))); {1244652}{但通过 pstr 可以找到 str}ShowMessage(pstr^); {ABCDE}
end;

程序运行后, 字符串所在的内存基本上是下面这个样子(以字节为单位), 上例中的 n 标识着 ↓ 的位置:

A B C D E

换二进制图示一下:

00001010 00001011 00001100 00001101 00001110

如果只看二进制, 这个数据到底是什么很难知道; 再说它为什么非得是字符串 "ABCDE" 呢? 这可不一定.

下面的例子中, 我们先是权且把它当作字符串, 但随着指针的移动, 字符串也在变化.

然后, 有分别把它分别用 Byte 指针(PByte) 和 Integer 指针(PInteger) 去读取它, 也会得到相应的值.

完整示例如下:


unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Button2: TButton;Button3: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);procedure Button3Click(Sender: TObject);end;varForm1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
varstr: string;ps: PChar;n: Cardinal;
beginstr := 'ABCDE';ps := PChar(str);n := Cardinal(ps);//n := Cardinal(str); {这行可以代替上面两行}ShowMessage(IntToStr(n)); {结果是 Windows 随机管理的}ShowMessage(PChar(n));   {ABCDE}ShowMessage(PChar(n+1)); {BCDE}ShowMessage(PChar(n+2)); {CDE}ShowMessage(PChar(n+3)); {DE}ShowMessage(PChar(n+4)); {E}
end;procedure TForm1.Button2Click(Sender: TObject);
varstr: string;n: Cardinal;pb: PByte;
beginstr := 'ABCDE';n := Cardinal(str);ShowMessage(IntToStr(n)); {4571140; 这是我这里的结果, 这是随机的}pb := PByte(n);ShowMessage(IntToStr(pb^)); {65}pb := PByte(n+1);ShowMessage(IntToStr(pb^)); {66}
end;procedure TForm1.Button3Click(Sender: TObject);
varstr: string;n: Cardinal;pint: PInteger;
beginstr := 'ABCDE';n := Cardinal(str);ShowMessage(IntToStr(n)); {4571140; 这是我这里的结果, 这是随机的}pint := PInteger(n);ShowMessage(IntToStr(pint^)); {1145258561}pint := PInteger(n+1);ShowMessage(IntToStr(pint^)); {1162101570}
end;end.

上面的第三个程序段的结果或许让你迷惑:
第一个结果, 应该和 "ABCD" 有点关系才对啊, 怎么是: 1145258561 ?
第二个结果, 应该和 "BCDE" 有点关系才对啊, 怎么是: 1162101570 ?

为什么呢? 这当然没错, 听我解释:
1145258561 转换成十六进制是: 44434241, 写得清楚一点是: $44 $43 $42 $41; 还记得 Intel 等当下流行的 CPU 安排数据是倒着的吗?

自己算算下一个, 用附件中的计算器即可.


转载于:https://my.oschina.net/hermer/blog/319544

谈谈 Delphi 的类型与指针[2]相关推荐

  1. Delphi 记录类型- 结构指针

    转自:万一老师的 Delphi 博客 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphi ...

  2. 探究:如何判断Delphi中的对象指针是否可用

    2019独角兽企业重金招聘Python工程师标准>>> 近日,在网上看到有网友问曰:如何确定一个对象指针是否可用?也就是说,如何确定一个对象指针是否指向一个真正可用的对象实例?其实这 ...

  3. delphi Dword类型转换为记录record

    typedef struct { HACMDRIVERID hadid;//指向HACMDRIVERID的句柄 WORD wFormatTag;//32位无符号整型 格式标签 } FIND_DRIVE ...

  4. 关于空指针(指针指向为NULL)和void类型的指针的理解

    正在学C,书上老说空指针,或者说void指针,对于我这样的生手来说,理解非常容易造成混淆,因为void这个单词的意思也是空,到底空指针的意思是指指向地址为空的类型呢,还是指void类型的指针呢 (1) ...

  5. 指针类型和指针类型转换的理解

    前几天在判断  "值相同的两个指针所指向的变量的值可以不同 "  这句话时,发现自己对指针类型一些概念仅仅是记住了结论.于是查阅了一些资料,记录一下一些与指针类型和指针类型转化相关 ...

  6. void 类型的指针

    void指针是空类型的指针,也称为无类型的指针,它不指向任何类型,即它仅仅是个地址.因此void指针不能进行指针运算,也不能取其所指向的数据的值 只有将void指针跟其他类型的指针相关联,才能使用他, ...

  7. java char指针数组_简单总结C语言中各种类型的指针的概念

    C语言中有很多关于指针的使用,指针也是C语言的灵魂所在,而且C语言中也有很多有关指针的概念,这里学习并总结了一些知道的概念. 常量指针:首先它是一个指针,常量只是用来修饰指针的定语.其定义如下: ch ...

  8. c 指针打印变量_C程序打印不同类型的指针变量的大小。

    c 指针打印变量 Any type of pointer variable takes the same memory bytes in the memory, because they are us ...

  9. LPVOID是一个没有类型的指针

    LPVOID是一个没有类型的指针,也就是说你可以将任意类型的指针赋值给LPVOID类型的变量(一般作为参数传递),然后在使用的时候再转换回来. 可以将其理解为long型的指针,指向void型. 2示例 ...

  10. c语言的各种类型的指针,简单总结C语言中各种类型的指针的概念

    2016 这篇文章主要简单总结了C语言中各种类型的指针的概念,指针可以说是C语言本身所具有的最大特性,平时根据不同使用场合习惯地将其简单分类,需要的朋友可以参考下 C语言中有很多关于指针的使用,指针也 ...

最新文章

  1. OpenCV图像处理使用笔记(三)——单通道的Mat对象强转为三通道的Mat对象
  2. 软件设计原则(七)合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
  3. java中常量final的用法_详解Java中final的用法
  4. cmd使用另一个Oracle的sid,(转发备用)Oracle SID在本机上已经存在,请指定一个不同的SID”的解决办法...
  5. 克隆ubuntu硬盘_使用Ubuntu Live CD克隆硬盘
  6. Java IdentityHashMap putAll()方法与示例
  7. 紫光展锐【软件工程师】面经
  8. IOCP扩展方法AcceptEx, DisconnectEx, GetAcceptExSockaddr用法示例
  9. Async和Await简介
  10. SharePoint 2010 大局观(1~3)
  11. 动手学数理统计(2)
  12. heic转换成jpg,学会这个方法就够了
  13. PCB设计培训,Layout工程师培训,射频基带技术培训,硬件技术培训,驱动开发培训
  14. 7款最好用的图片无损,视频无损压缩软件
  15. 知识付费平台包括哪些功能版块?
  16. python 找出其中不含有重复字符的最长子串的长度
  17. 51nod 1556 计算(默慈金数)
  18. 《你好,放大器》----学习记录(六)
  19. 大疆笔试中的涉及矩阵最小二乘求解思路
  20. SplitIt视频文件快速分割工具操作技巧

热门文章

  1. 详细设计 存储分配_【存储论文笔记】Windows Azure Storage
  2. python json dump_为什么json.dump()没有以\ n结尾? - python
  3. python接口自动化登录后保存个人简介_python接口自动化三(登录及发帖)
  4. java io 常用类库_JDK 中需要掌握的常用类库
  5. 力扣-1929 数组串联
  6. 宝塔面板连接阿里云服务器、及部署网页项目教程
  7. 7-9 成绩转换 (15 分)
  8. 实时查看Linux IO复用情况
  9. 第八届蓝桥杯省赛真题--最大公共子串
  10. mysql知识点拾遗梳理