• 关于动态数组、静态数组转换为字符串的一些问题 给 "厨师" 的回复


    问题来源: http://www.cnblogs.com/del/archive/2008/05/21/1192113.html#1204252

    首先, 只有字符类型的数组才可以直接转换为字符串!
    //这是静态数组的例子:
    var
      Arr: array[0..9] of Char;
      s: string;
      p: PChar;
      i: Integer;
    begin
      {给 Arr 赋值: A B C D E F G H I J}
      for i := Low(Arr) to High(Arr) do
        Arr[i] := Chr(65+i);
    
      {把 Char 数组赋给 string}
      s := Arr;
      ShowMessage(s); {ABCDEFGHIJ}
    
      {把 Char 数组赋给 PChar}
      p := PChar(string(Arr));
      ShowMessage(p); {ABCDEFGHIJ}
    
      {直接把 Char 数组赋给 PChar, 会有意想不到的结果, 因为缺少 #0 结束}
      p := Arr;
      //p := @Arr;    {或者这样}
      //p := @Arr[0]; {再或者这样}
      ShowMessage(p); {ABCDEFGHIJ未知数据}
      {这种方式偏偏是我们在使用 API 函数时用得最多的, 但 API 函数都会返回给 #0 结束的, 所以没有问题}
    end;
    
    
    //这是动态数组的例子:
    var
      Arr: array of Char;
      s: string;
      p: PChar;
      i: Integer;
    begin
      {给 Arr 赋值: A B C D E F G H I J}
      for i := 0 to 9 do
      begin
        SetLength(Arr, i+1);
        Arr[i] := Chr(65+i);
      end;
    
      Pointer(s) := Arr;
      //Pointer(s) := @Arr[0]; {或者这样}
      ShowMessage(s); {ABCDEFGHIJ}
    
      p := PChar(Arr);
      //p := @Arr[0]; {或者这样}
      ShowMessage(p); {ABCDEFGHIJ}
    end;
    
    要想彻底理解上面的操作, 需要知道静态数组与动态数组指针问题.
    var
      ArrS: array[0..9] of Char; {静态数组}
      ArrD: array of Char;       {动态数组}
      i: Integer;
    begin
      {设置动态数组大小, 并给两个数组赋值}
      SetLength(ArrD, 10);
      for i := 0 to 9 do
      begin
        ArrS[i] := Char(65+i);
        ArrD[i] := Char(97+i);
      end;
    
      {测试赋值结果}
      ShowMessageFmt('%s, %s', [ArrS[0], ArrD[0]]); {A, a}
    
      {静态数组变量的指针(而非变量本身)和它的第一个元素的指针是同一个}
      ShowMessageFmt('%p, %p', [@ArrS[0], @ArrS]);  {0012FDE2, 0012FDE2}
    
      {动态数组变量本身(而非变量的指针)就是一个指针, 它和第一个元素的指针也是同一个}
      ShowMessageFmt('%p, %p, %p', [ArrD, @ArrD[0], @ArrD]); {00E7C970, 00E7C970, 0012FDEC}
    end;
    
    另外, 动态数组的构造和静态数组完全不同, 它和 String 的构造 倒是有些相似.

    每个动态数组第一个元素前还有 8 个字节, 没 4 个字节记录一个整数;

    最前面 4 个字节是用于生存管理的引用计数(当引用计数为 0 时数组自动释放);

    第一个元素之前的 4 个字节记录数组的长度. 测试如下:
    var
      Arr1,Arr2: array of Char; {定义两个动态数组, 其中一个是为了测试引用计数}
      i: Integer;  {用于指针运算}
      p: PInteger; {用于读取动态数组前面的两个 32 位整数}
    begin
      SetLength(Arr1, 10); {设置数组长度}
      Arr2 := Arr1;        {增加一个引用}
      i := Integer(Arr1);  {获取数组地址(这也是数组第一个元素的位置)}
    
      {获取动态数组的长度}
      i := i-4;
      p := PInteger(i);
      ShowMessage(IntToStr(p^)); {10}
    
      {获取动态数组的引用计数}
      i := i-4; {再减 4}
      p := PInteger(i);
      ShowMessage(IntToStr(p^)); {2}
    end;
    
  • 相关阅读:
    set--常见成员函数及基本用法
    [Swust OJ 1026]--Egg pain's hzf
    [HDU 1111]--Secret Code
    [Swust OJ 1139]--Coin-row problem
    [Swust OJ 781]--牛喝水
    [Swust OJ 1132]-Coin-collecting by robot
    [Swust OJ 249]--凸包面积
    HTTP 请求头中的 X-Forwarded-For
    HTTP 下载文件中文文件名在 Firefox 下乱码问题
    数据挖掘系列 (1) 关联规则挖掘基本概念与 Aprior 算法
  • 原文地址:https://www.cnblogs.com/del/p/1204264.html
Copyright © 2020-2023  润新知