• 4个字节就相当于移动一位,原来指针是这样用的


    1字节等于8位,是8位二进制位

    移动了一位,等于4字节,

    4个8位 等于32位。

    各种流在存取、操作数据的机理上都是一样的。说白了,就是“无类型”,它不管
    你是整型、字符串型、图象、还是声音,只要你告诉它要读写的数据的首地址和长度,就
    可以了。也正是由于这个原因,使用流读写数据的速度都比较快。Delphi之所以还要派生
    出各种各样类型的流,其实就是为了使操作某些具体类型的数据时更方便、更容易一些而
    已。比如:TMemoryStream中有个Memory属性,它就是这块内存的首地址,使得我们直接
    操作内存变得方便了;TStringStream中有个DataString属性,使我们象读一个字符串一
    样读取整个流......但话说回来,我偏要用TMemoryStream处理字符串,难道不行吗?当
    然行了!或者说处理字符串时用TStringStream就一定最方便吗?不一定啊!其中就是用TMemoryStream来处理字符串的,不是很巧妙、很方便吗!

    [问题2]
    理解指针,主要有两个方面,一个是指针变量本身所占内存的大小,另一个是指针所指向
    的数据的数据类型的大小(或长度)。
    从前者来看,各种类型的指针都是一样的,都没什么区别,因为在Win32系统下,指针变量
    都占4个字节,你可以自己试试,IntToStr(sizeof(Pointer));但从后者来看,就有点不一
    样了,这主要就表现在指针移动的步长可能是不一样的,就是说,你让指针移动一个单位,
    实际内存中指针移动的字节数是不一样的。请看下面的例子:
    var
      ms: TMemoryStream;
      pInt: ^Integer;
    //  pInt: PChar;
      i: Integer;
      j: Integer;
    begin
      ms := TMemoryStream.Create; //声明并建立一个内存流对象
      i := 123;
      ms.Write(i, sizeof(Integer)); //向流中写入一个整型值123
      i := 99;
      ms.Write(i, sizeof(Integer)); //向流中再写入一个整型值99
      pInt := ms.Memory; //将这块内存的首地址,也就是指向123的那个地址
                         //赋给基类型是整型的指针变量pInt
      Inc(pInt); //将指针移动一个单位,由于基类型是整型,整型是占4个字节的
                 //所以,这里虽然只是移动了一个单位,但却相当于移动了4个字节的长度,
                 //也就是这时指针指向了99这个整数的位置
      Move(pInt^, j, sizeof(Integer)); //将99取出来
      Caption := IntToStr(j);          //显示一下,果然是99
      ms.Free;
      {
        如果将上面的pInt: ^Integer;改成pInt: PChar;其他地方不动,你会发现读出来的数
        据不是99,而是内存中的一个随机值,但如果你再将Inc(pInt);改成Inc(pInt, 4);
        就正确了。原因就是PChar的基类型是Char,而它是占1个字节的,所以,你移动一个
        单位,只移动了一个字节,当然得不到正确的答案了。
      }
    end;
    !!!!这就是各种指针的本质区别!!!!
    至于Pointer是无类型的指针,也就是它可以指向任何类型的数据,你将它强制转换成整型,
    它就是^Integer,你将它强制转换成字符型,那它就是PChar.....我再将上面的代码改成
    Pointer,你就明白了
    type
      TPInt = ^Integer;
    var
      ms: TMemoryStream;
      pInt: Pointer; //这里
      i: Integer;
      j: Integer;
    begin
      ms := TMemoryStream.Create;
      i := 123;
      ms.Write(i, sizeof(Integer));
      i := 99;
      ms.Write(i, sizeof(Integer));
      pInt := ms.Memory;
      Inc(TPInt(pInt)); //这里,其实,使用预定义的整型指针也行,我就是为了说清楚一点
                        //Inc(PInteger(pInt));
      Move(pInt^, j, sizeof(Integer));
      Caption := IntToStr(j);
      ms.Free;
    end;

    全文:http://www.2ccc.com/news/Html/?957.html

  • 相关阅读:
    使用taobao的npm镜像源,同时安装nrm镜像工具
    文档工具
    javascript基础语法备忘录-变量和数据类型
    a :hover 和a:hover 区别
    我使用的brackets插件
    使用git将自己的代码同时保存在多个代码托管平台
    mac os安装macvim
    ubuntu下安装录屏软件
    解决 eclipse cdt 运行时控制台乱码解决
    Chrome开发者工具详解(五)之Network面板
  • 原文地址:https://www.cnblogs.com/yzryc/p/6401649.html
Copyright © 2020-2023  润新知