(okwary) 小叹的学习园地

与天斗?不够高~ 与地斗?不够阔 与人斗? 脸皮不够厚

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

string

 

var
  str: string;   {定义}
begin
  str := '小白'; {赋值}
  ShowMessage(IntToStr(Length(str))); {长度是: 4}
end;

//长字符串 AnsiString; 在当前版本(2007)中的默认状态下, String 就是AnsiString:
var
  str: AnsiString;
begin
  str := '小白';
  ShowMessage(IntToStr(Length(str))); {长度是: 4}
end;

//宽字符串 WideString (效率不及 AnsiString):
var
  str: WideString;
begin
  str := '小白';
  ShowMessage(IntToStr(Length(str))); {长度是: 2}
end;

//定长字符串String[n]:
var
  str1: String[6];       {指定大小不能超过 255}
  str2: String[100];   

begin
  str1 := '小白';      {少给了也会占那些内存}
  ShowMessage(str1);                   {小白}
  ShowMessage(IntToStr(Length(str1))); {4; 这是字符串的长度}
  ShowMessage(IntToStr(SizeOf(str1))); {7; 这是占内存大小}
  str1 := '小白的 Delphi 博客';{多给了会被截断}
  ShowMessage(str1);                   {小白的}
  ShowMessage(IntToStr(Length(str1))); {6; 这是实际保存的字符串长度}
  ShowMessage(IntToStr(SizeOf(str1))); {7; 这是占内存大小}

  {问题: 不是声明大小为 6 吗? 怎么 SizeOf 是 7 ? }
  {因为定长字符串会多出一个首字节来记忆字符串的实际长度}

  {举例说明, 如果给 str2 按如下赋值, 那它的首字节(str2[0])肯定储存着字符 'A'}
  str2 := 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'; {65个}
  ShowMessage(str2[0]);                {A}
  ShowMessage(IntToStr(Ord(str2[0]))); {65; 这是 'A' 在 ASCII 序列中的序号, 用的就是它}
  {那以后可以用 Ord(str2[0]) 来代替 Length 判断字符串的长度吗? }
  {对定长字符串是可以的; 不但能读取, 还可以像 SetLength 一样设置}
end;

 

var 
   str,s1,s2:string;
   pint: PInteger;
begin 
   str := Self.Text; { str 指向了窗体标题所在的内存位置}
   s1 := str;        {给 s1 赋值}
   s2 := str;        {给 s2 赋值}{ 现在窗体标题已经有了 str、s1、s2 三个引用} 
   ShowMessage(IntToStr(Integer(str))); {15190384} 
   ShowMessage(IntToStr(Integer(s1)));  {15190384} 
   ShowMessage(IntToStr(Integer(s2)));  {15190384}  {str、s1、s2指向内存位置一样} 
   pint := PInteger(Integer(str) - 4);  {向左偏移 4 个字节就是字符串长度的位置}
   ShowMessage(IntToStr(pint^));       
   pint := PInteger(Integer(str) - 8);  {向左偏移 8 个字节就是字符串的引用计数}
   ShowMessage(IntToStr(pint^)); {3}    {读出它来(肯定是3):}
end;

{当某段字符串内存的引用计数为 0 时, Delphi 就会自动释放它; 这也是字符串不需要手动释放的原因.我在测试时发现: 所有常量和非全局的变量的引用计数一直是"-1". }

{ String 的指针地址及实际的内存地址 }

var 
  str:  string;
  pstr: PString;
  pc:   PChar;
begin  {在没有给 str 赋值以前, 既然声明了, 就有了指针地址(@str):}
  ShowMessage(IntToStr(Integer(@str))); {XXXXXX; 这是在栈中的 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 := PChar(Integer(str));            {通过实际地址获取字符串, 其中的 pc 是前面定义的字符指针}
  ShowMessage(pc);    {Delphi}
end;

 


ShortString

//ShortString; 它相当于 String[255]
var
  str: ShortString;
begin
  str := '小白的 Delphi 博客';
  ShowMessage(str);                   {小白的 Delphi 博客}
  ShowMessage(IntToStr(SizeOf(str))); {256; 这是大小}
  ShowMessage(IntToStr(Length(str))); {18 ; 这是实际长度}
  ShowMessage(IntToStr(Ord(str[0]))); {18 ; 这是从首字节中取出的长度}
end;

 

 

 

 

 

Char


{   Char、AnsiChar  单字符只有 1 字节大小 ,取值范围是: #0..#255,用十六进制表示是: #$0..#$FF }


var
  c: Char;
begin
 
  c := #65;  ShowMessage(c); {A}        {用十进制方式赋值:       }
  c := #$41;  ShowMessage(c); {A}       {用十六进制方式赋值:     }
  c := Chr(65);   ShowMessage(c); {A}   {用 Chr 函数代替 # 符号  }
  c := Chr($41);  ShowMessage(c); {A}   {用 Chr 函数代替 # 符号  }

  ShowMessage(IntToStr(Length(c))); {1} {Char 长度当然会是 1     }
  c := 'B';                             {Char、AnsiChar 和 1 字节长度的字符串是兼容的)}
  ShowMessage(c); {B}
end;

 

WideChar

 

{ WideChar UniCode字符,  WideChar 是占 2 字节大小,取值范围是: #0..#65535, 用十六进制表示是:#$0..#$FFFF}

 

var
  c: WideChar; {WideChar 兼容了 AnsiChar 的 #0..#255; 但占用了 2 字节大小}
begin
 
  c := #65;
  ShowMessage(c); {A}
  ShowMessage(IntToStr(Length(c))); {1; 这是字符长度}
  ShowMessage(IntToStr(SizeOf(c))); {2; 但占用 2 个字节}
 
  c := #$4E07;    {用十六进制赋值}
  ShowMessage(c); {万}
  ShowMessage(IntToStr(Length(c))); {1; 这是字符长度}
  ShowMessage(IntToStr(SizeOf(c))); {2; 但占用 2 个字节}
 
  c := #19975;    {用十进制赋值}
  ShowMessage(c); {万}
 
  c := 'B';
  ShowMessage(c); {万}         {如果不超出 #255 的范围是可以直接赋值的}
 
  //c := '万';                 { 错误 这是 Delphi 的支持问题, 估计 Delphi 2008 应该可以解决}

 
  c := WideString('万')[1];    {可以这样变通一下:}
  ShowMessage(c); {万}
 
end;

 

PChar

{ PChar、PAnsiChar 字符指针; 在当前版本(2007)中它们没有区别.Delphi 的 PChar(PAnsiChar)对应Windows API 中的字符串; }

var
  p: PChar;
  str: string;
begin
 
  p := '小白';                      {可以给 PChar 直接赋予字符串常量}
  ShowMessage(p);                   {小白}
  ShowMessage(IntToStr(Length(p))); {4}

 
  str := '小白的 Delphi 博客';       {给变量值需要转换}
  p := PChar(str); {转换}
  ShowMessage(p);                    {小白的 Delphi 博客}
  ShowMessage(IntToStr(Length(p))); {18}
end;
 
{ PChar^ 类型的用法 }

var
  p: PChar;
begin
  p := PChar('abcd');
  ShowMessage(p);    {abcd}
  ShowMessage(p^);   {a}
  p := p + 2;
  ShowMessage(p^);   {c}
  Dec(p);
  ShowMessage(p^);   {b}
  ShowMessage(p);    {bcd}
end;


{ PChar 中的字符遍历 }
var
  p: PChar;
begin
  p := PChar('abcd');
  while p^ <> #0 do
  begin
    ShowMessage(p^); {分别显示: a、b、c、d}
    Inc(p);
  end;
end;


{替代缓冲区与内存分配的简单方法}
var
  p: PChar;
begin
  p := PChar(StringOfChar(#0, 255));
  GetWindowsDirectory(p, 255); {譬如获取 Windows 目录}
  ShowMessage(p);              {C:\WINDOWS}
end;


{ PWideChar 宽字符指针 }
var
   p: PWideChar;
   str: WideString; {注意这里不是String}

begin  {可以给 PWideChar 直接赋予字符串常量} 
   p := '小白';
   ShowMessage(p);                   {小白} 
   ShowMessage(IntToStr(Length(p))); {2}    {给变量值需要转换} 

   str := '小白的 Delphi 博客';
   p := PWideChar(str);              {转换}
   ShowMessage(p);                   {小白的 Delphi 博客} 
   ShowMessage(IntToStr(Length(p))); {13}
end;


 

array


{ array[ ] of type 字符串与字符数组}

var 
   arr: array[0..5] of Char;
   str: string;
begin 
  //可以把字符串常量直接赋给字符数组; 但超界不行
  arr := 'Delphi';
  ShowMessage(arr); {Delphi}  {可以把字符数组直接赋给字符串变量}
  str := arr;
  ShowMessage(str); {Delphi}  {但不能把一个字符串变量赋给字符数组}
  //arr := str;     {错误}  {其实字符串内部也是包含了一个字符数组, 所以能索引访问, 不过它的索引起始于 1} 
 ShowMessage(str[1]); {D} 
 ShowMessage(arr[0]); {D}
end;


var 
   arr: array[0..6] of Char; 
   p: PChar;
begin 
   arr := 'Delphi';           {如果直接把字符数组给字符指针, 结果不保险, 因为字符指针要找空字符(#0)结束}
   arr[Length(arr)-1] := #0;  {把数组的最后一个元素给 #0 就可以了} 
   p := arr;  ShowMessage(p); {Delphi}  {假如把 #0 给到中间会怎样?} 
   arr[3] := #0;
   p := arr;
   ShowMessage(p); {Del; 给截断了}
end;

 

 

//取值方法1: 用字符数组(经常被称作"缓冲区")

var
  arr: array[0..254] of Char;
begin 
  GetWindowText(Handle, arr, 255);
  ShowMessage(arr); {Form1}
end;


//取值方法2: 使用 GetMem 给 PChar 分配内存

var
  p: PChar;

begin
   GetMem(p, 255); {分配内存} 
   GetWindowText(Handle, p, 255); 
   ShowMessage(p); {Form1} 
   FreeMem(p);     {释放内存}
end;


//取值方法3: 用 GlobalAlloc 分配全局内存(比 GetMem 慢)

var
  p: HGLOBAL;
begin
  p := GlobalAlloc(0, 255); {参数一给 0 或 GMEM_FIXED 表示分配的是固定内存}
  GetWindowText(Handle, PChar(p), 255); 
  ShowMessage(PChar(p)); {Form1}
  GlobalFree(p);         {释放内存}
end;


//取值方法4: 直接使用 string; 需要先 SetLength, 然后再去除空白:

var
  str: string;
begin 
  SetLength(str, 255); {先设定 str 的长度}
  GetWindowText(Handle, PChar(str), 255);  {但此时 str 的长度是 255 啊!}
  str := PChar(str); {这样可以得到实际长度的字符串}
  ShowMessage(str);  {Form1}
end;

{ 定长字符串不是 #0 结束的, 和 API 不好兼容, 一般不用于 API 中. }

{ Char,byte 类型与其编码值的转换 }

var
  b: Byte;  c: Char;
begin 
  b := Ord('A');   {返回: 65} 
  b := Ord(#65);   {返回: 65} 
  b := Ord($41);   {返回: 65} 
  b := Ord(#$41);  {返回: 65} 
  b := Byte('A');  {返回: 65} 
  b := Byte(#65);  {返回: 65} 
  b := Byte($41);  {返回: 65} 
  b := Byte(#$41); {返回: 65}
  c := Chr(65);    {返回: A }
  c := Chr($41);   {返回: A } 
  c := Char(65);   {返回: A } 
  c := Char($41);  {返回: A }
end;

 

posted on 2008-12-18 14:46  okwary  阅读(437)  评论(0编辑  收藏  举报
ggg