程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
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