關於動態數組、靜態數組以及轉換爲字符串的一些問題

首先, 只有字符類型的數組才能夠直接轉換爲字符串!html


//這是靜態數組的例子:
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;
相關文章
相關標籤/搜索