关于内存和指针操作,数据类型转换本质的理解

来源:互联网 发布:姚期智回国 知乎 编辑:程序博客网 时间:2024/05/16 05:12
Delphi 关于内存和指针操作,数据类型转换的本质的理解。
很多朋友问的问题感觉都是没有理解内存和指针与数据类型之间的关系。想解释一下。
   很少写东西,觉得有些东西不好表达,就想到那说到那了,希望能提供一些帮助。
指针的使用,和使用指针直接读取数据是软件开发中经常使用到的技术,也是软件开发所需要掌握的基础,理解并能灵活的使用指针来操作内存,读写数据是软件开发必须要熟练掌握的基本。
内存可以看成是下图一个个的带颜色的小格子,每个小格子是一个字节的长度,<图一>共显示了8个小格式了,每个格子是一个字节,每个字节是由8bit 组成。

<图一>
因为我们一般操作的最小单元就是一个字节,所以展示内存布局的时候就用<图二>了。
 
<图二> 图上方的 1 2 ,3 …8 代表每个格子的地址。就象是房号一样。
  内存的使用的是小单位是一个字节,Byte 类型和Char类型都是一个字节的长度。SizeOf(Byte)返回值是1,对计算机来说并不知道数据类型是 Byte还是Char ,它只是知道这个8个bit 的数据。
Var
  B:Byte; 
  C:Char;
Begin
  C:=’A’; 
  B:=65;
End;
这两上类型在内存中的保存都是二进制:01000001 ,当然因为我们能操作的最小是一个字节,即8个二进制长。01000001用十六进制表示为: $41。@B 表示得到数据B所在的内存位置,即数据所保存的房间号。如<图二>,@B将所返回 1 。

如果告诉你说这个字节保存的是 $41 ,你可能将它看成是 Byte 类型,也可以看成是 Char类型,这些数据类型只是人们自己为了操作方便而起的名字罢了。
Size(Word) 返回的长度是2 ,即两个字节。Var W:Word;  定义一个Word类型的变量,@W将返回的是第一个房间号,因为系统知道Word 是占用两个字节,所以在操作时候会将两个房间的数据来操作。如 @W返回的是 3 ,如<图三>
 
<图三>
则W的值是 17475 十六进制 $4443 。
 Arr1:Array[0..1] of Byte; 一个占两个字节的数组,它的房号是 @Arr1 或者 @Arr1[0]。
 如果 @Arr1 的值也是 3 则 Arr1[0]为$43 Arr1[1]为$44。
 Arr2:Array[0..1] of  Char ; 也是一个占两个字节的数组,如果 @Arr2 的值也是 3 则 Arr2[0]为C Arr2[1]为D。因为AScall码表中用 $43 即 67表示大字字母 C。用 $44 即 68表示大字字母 D。
以上说明,内存中保存的只是一些数字,至于这个数字是代表什么意思,是我们自己决定的,我们定义了很多的数据类型,如 Byte;Char;Word;Integer;Array [0..1] of Byte;Array [0..1] of  Char;还有更多我们自己定义的结构。如
TMyInfo= packet record
  ID:Byte;
  年龄:Byte;
  进球数:Word
End;

Var MyInfo: TMyInfo;  @ MyInfo返回的地址是3 ,那ID=67,年龄=68岁,进球数=69个。
我们也可定义成如下这样的结构。说明每个 TMyInfo2结构占用SizeOf(TMyInfo2)=5 字节
TMyInfo2=packet record
  进球数:Word
  ID: Word;
  年龄:Byte;
End;
Var MyInfo2: TMyInfo2;  @ MyInfo2返回的地址是3 ,则内存中的数据表示的意思就成了,进球数=17475($4443) ,ID= 17989个($4645),年龄=71($47)岁
以上两个结构的内存布局是一样的,大小也是一样的,只是我们对它的解释不同,两个结构体就象是两个模具,对内存数据的意义根据模具的描述来确定。
上面两个结构也可以和下面的这个结构相同
TMyInfo2=Pack record
  ID:Integer;
  年龄:Byte;
End;
就上面的内存布局 ID =1178944579($46454443) 年龄=71($47)岁
也可以和下面的内存布局一样
   Var Arr3:Array [0..5] Byte; Var Arr4:Array [0..5] Char;
Arr3 [0]=67;Arr3 [1]=68;Arr3 [2]=69;Arr3]=70;Arr3 [4]=71;
  Arr4[0]=C;Arr4[1]=D;Arr4[2]=E;Arr4[3]=F;Arr4[4]=G;
  
  我们时刻要明白我们定义的数据在内存中的真实布局情况是什么样子,我们对各种数据类型的转换,指针的移动就更明确了,我们可以将一个内存块的数据看成一个数组,也可以看成一个结构体,也可以看成是一个个的数字,在这些数据类型之间我们可以互相转换。也可以将一个结构体复制到一个数组中。ComyMemory 进行数据的复制是不管内存中的数据是什么业务意义的,只是将内存块进行复制罢了。

  对内存操作,指针操作不理解的朋友都是没有明白这些操作,没有理解内存和数据类型的关系。理解了这些以后就可以更好的理解软件开发的过程,更好的解释很多的错误原因了。