Delphi Xe的字符及字符串[1] - string、AnsiString、WideString、String[n]、ShortString

最常用的 string,以前版本(2007)中的默认状态下, String 就是 AnsiString,Xe版本String就是WideString。注意:DelphiXE中使用UniCodeString下标引用得到的字符的值,而使用AnsiString下标引用得到的却是字节的值。

AnsiChar类型变量使用单字节来表示一个字符,WideChar使用两个字节来表示一个字符。WideChar和AnsiChar类型的变量之间不能相互赋值。

AnsiString实质上是一个指针类型,与普通的指针不同,此类型的指针专用于指向字符串。利用标准函数SizeOf()可知此类型变量在内存中占用4个字节。所以AnsiString最小值为4byte,而非0byte,也就是说,一个空字符串占用4个字节。

字符串表示由字符组成的序列。Delphi中常用的字符串类型主要有四种:ShortString、AnsiString、WideString、UnicodeString。四种字符串的简要信息如下:

 

 类型

最大长度 

所需内存 

用途 

 ShortString

 255 byte

 2-256 byte 

容纳AnsiChar 

 AnsiString

 2GB

 4-2GB 

容纳AnsiChar 

 WideString

 2GB

 4-2GB

容纳WideChar

 UnicodeString

 2GB

 4-2GB 

容纳Unicode码字符

 

 以下调试例子详尽对比了中文字符和因为字符在所有字符类型中的区别:

var shortStrArray:string[2];str:string;ansiStr:AnsiString; shortstr:ShortString;vchar:array[0..254] of Char;
begin
  //AnsiString在栈中保存
  ansiStr := '胜利';
  ShowMessage(ansiStr); //胜利
  ShowMessage(IntToStr(Length(ansiStr)));//占4字符位,因为AnsiString是用AntiChar作单位计算,中文需要2个AntiChar来存储
  ShowMessage(IntToStr(SizeOf(ansiStr)));//指针占8字节

  ansiStr := 'ab';
  ShowMessage(ansiStr);
  ShowMessage(IntToStr(Length(ansiStr)));//占2字符位
  ShowMessage(IntToStr(SizeOf(ansiStr)));//指针占8字节

  //String在栈中保存
  str := '胜利';
  ShowMessage(str); //胜利
  ShowMessage(IntToStr(Length(str)));//占2字符位,因为string是用wideChar作单位计算
  ShowMessage(IntToStr(SizeOf(str)));//指针占8字节

  str := 'ab';
  ShowMessage(str); //胜利
  ShowMessage(IntToStr(Length(str)));//占2字符位,因为string是用wideChar作单位计算,在内存中它以0062,0061形式保存每个英文独占2个字节
  ShowMessage(IntToStr(SizeOf(str)));//占8字节

  //数组保存在堆中
  //string[2]等于转为ShortString类型,在堆里保存
  shortStrArray := '胜利';
  ShowMessage(shortStrArray); //胜
  ShowMessage(IntToStr(Length(shortStrArray)));//2,因为截断了,所有只有2个AnsiChar位置
  ShowMessage(IntToStr(SizeOf(shortStrArray)));//3,如果是数组,则表示是数组内存模块大小,因为字符数组头一个字符用来记录字符长度,shortStrArray[0]值为2个字符

  //数组保存在堆中
  //ShortString等于String[255],ShortString = Array[0.255] of AnsiChar;
  shortstr := '胜利';
  ShowMessage(shortstr);
  ShowMessage(IntToStr(Length(shortstr)));//占4字符位,因为没有截断,所有有4个AnsiChar位置
  ShowMessage(IntToStr(SizeOf(shortstr)));//256,因为字符数组头一个字符用来记录字符长度所以长度为255+1=256


  vchar := 'abc';
  ShowMessage(vchar[0]);//显示a
  ShowMessage(IntToStr(Length(vchar)));//255
  ShowMessage(IntToStr(SizeOf(vchar)));//510 后面两位因为需要加零结束符而占掉了位置
end

 

以下另外一个调试例子:

//定长字符串
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;

再看看摘自万一博客关于Char的介绍和理解

//单字符 Char、AnsiChar (在目前版本(2007)中, 它们是一回事, 只有 1 字节大小)
var
  c: Char; {Char 类型的取值范围是: #0..#255, 用十六进制表示是: #$0..#$FF}
begin
  {用十进制方式赋值:}
  c := #65;
  ShowMessage(c); {A}

  {用十六进制方式赋值:}
  c := #$41;
  ShowMessage(c); {A}

  {用 Chr 函数代替 # 符号}
  c := Chr(65);
  ShowMessage(c); {A}
  c := Chr($41);
  ShowMessage(c); {A}

  {Char 长度当然会是 1}
  ShowMessage(IntToStr(Length(c))); {1}

  {Char、AnsiChar 允许这样方便地赋值(也就是和 1 字节长度的字符串是兼容的):}
  c := 'B';
  ShowMessage(c); {B}
end;


//UniCode 字符 WideChar; 和 AnsiChar 不同, WideChar 是占 2 字节大小.
var
  c: WideChar; {WideChar 的取值范围是: #0..#65535, 用十六进制表示是: #$0..#$FFFF}
begin
  {WideChar 兼容了 AnsiChar 的 #0..#255; 但占用了 2 字节大小}
  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); {万}

  {如果不超出 #255 的范围是可以直接赋值的}
  c := 'B';
  ShowMessage(c); {万}

  {这样不行}
  //c := '万'; {这是 Delphi 的支持问题, 估计 Delphi 2008 应该可以解决}

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

  {用 WideChar 的方式显示我的名字}
  ShowMessage(#19975#19968);    {万一}
  ShowMessage(#19975 + #19968); {万一}
  ShowMessage(#$4e07#$4e00);    {万一}
end;


//字符指针 PChar、PAnsiChar; 在当前版本(2007)中它们没有区别.
var
  p: PChar;
  str: string;
begin
  {可以给 PChar 直接赋予字符串常量}
  p := '万一';
  ShowMessage(p);                   {万一}
  ShowMessage(IntToStr(Length(p))); {4}

  {给变量值需要转换}
  str := '万一的 Delphi 博客';
  p := PChar(str); {转换}
  ShowMessage(p);                   {万一的 Delphi 博客}
  ShowMessage(IntToStr(Length(p))); {18}
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;

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

turbocc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值