程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi 的字符及字符串[3] - String 中的秘密

Delphi 的字符及字符串[3] - String 中的秘密

編輯:Delphi

//String 的指針地址及實際的內存地址
var
 str: string;
 pstr: PString;
 pc: PChar;
begin
 {在沒有給 str 賦值以前, 既然聲明了, 就有了指針地址(@str):}
 ShowMessage(IntToStr(Integer(@str))); {1244652; 這是在棧中的 str 的指針地址}
 {但現在還沒有分配真正儲存字符串內存}
 ShowMessage(IntToStr(Integer(str))); {0; 0 就是 null}
 str := 'Delphi';
 {一旦賦值後...}
 ShowMessage(IntToStr(Integer(@str))); {1244652; 這是在棧中的 str 的指針地址}
 ShowMessage(IntToStr(Integer(str))); {4580800; 這是在堆中的 str 的實際地址}
 {通過指針地址獲取字符串, 其中的 pstr 是前面定義的字符串指針}
 pstr := @str;
 ShowMessage(pstr^); {Delphi}
 {通過實際地址獲取字符串, 其中的 pc 是前面定義的字符指針}
 pc := PChar(Integer(str));
 ShowMessage(pc);  {Delphi}
end;
一個字符串(AnsiString 或 String, 譬如是 "Form1" )在內存中是這樣儲存的:

F o r m 1

  黃色區域是真正存字符串的位置, 前面說的字符串所在的內存地址, 就是本例中的 "F" 所在的位置;

  藍色的四個字節儲存一個 Integer 值, 表示字符串的長度;

  最後紅色的一個字節儲存一個空字符(#0), 表示字符串的結束, 同時也是為了和 Windows 的 null 結束的字符串兼容;

  綠色的四個字節也是一個 Integer 值, 表示該字符串被引用的次數(也就是有幾個字符串的指針指向它).

  還是看例子吧:var
 str,s1,s2: string;
 pint: PInteger;
begin
 str := Self.Text; {把窗體標題給它吧; 現在 str 指向了窗體標題所在的內存位置}
 s1 := str;    {給 s1 賦值}
 s2 := str;    {給 s2 賦值; 現在窗體標題已經有了 str、s1、s2 三個引用}
 {str、s1、s2 的指針肯定不一樣; 但現在指向內存的同一個位置, 測試:}
 ShowMessage(IntToStr(Integer(str))); {15190384}
 ShowMessage(IntToStr(Integer(s1))); {15190384}
 ShowMessage(IntToStr(Integer(s2))); {15190384}
 {向左偏移 4 個字節就是字符串長度的位置, 讀出它來(肯定是5):}
 pint := PInteger(Integer(str) - 4);
 ShowMessage(IntToStr(pint^));   {5}
 {向左偏移 8 個字節就是字符串的引用計數, 讀出它來(肯定是3):}
 pint := PInteger(Integer(str) - 8);
 ShowMessage(IntToStr(pint^));   {3}
end;
當某段字符串內存的引用計數為 0 時, Delphi 就會自動釋放它; 這也是字符串不需要手動釋放的原因.

  我在測試時發現: 所有常量和非全局的變量的引用計數一直是 "-1".


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved