首先, 只有字符類型的數組才能夠直接轉換爲字符串!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;