Delphi字符串类型浅析_第1页
Delphi字符串类型浅析_第2页
Delphi字符串类型浅析_第3页
Delphi字符串类型浅析_第4页
Delphi字符串类型浅析_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、delphi字符串类型浅析 收藏参考资料«delphi 5开发人员指南“第2章object pascal语言”pascal精要“第7章 字符串操作”adelphi中string类型和char类型的比较”uobject pascal中string类型的内幕探讨”基本知识字符串类型ansistring这是pascal缺省的字符串类型,它由ansichar字符组成,其长度没有限制,同 时与null结束的字符串相兼容。shortstring保留该类型是为了向后兼容delphi 1.0,它的长度限制在255个字符内。widestring功能上类似于ansistring,但它是山wide cha

2、r字符(unicode字符集)组成的。 引入这种类型,主要是为了支持ole编程。pchar指向null结束的char字符串的指针,类似于c的char*或lpstr类型。pansichar指向null结束的ansichar字符串的指针。pwidechar指向null结束的widechar字符串的指针。字符类型ansichar,以8位表示(共有256个不同的符号)。widechar,以16位表示(共有64,000个不同的符号)。string类型注意:以下是指delphi2007以前的编译器(包括delphi2007)o1、缺省情况下,如果用如下的代码来定义字符串,编译器认为是ansistring字

3、符串:vars:string;/编译器认为s的类型是ansistring2、编译开关$日“$h编译开关”的值川来决定当变量声明为string时,它是被当作ansistring类型还是被 当作shortstring类型。当“$h”值为负时,string变量是shortstring类型;当“$h”值为 正时(缺省情况),string变量是ansistring类型。下而的代码演示了这种情况:var$h-sl:string;/s 1 是 shortstring 类型$h+s2:string;/s2 是 ansistring 类型使用$h规则的一个例外是,如果在定义时特地指定了长度(最大在255个字符内

4、),那么总 是 shortstringovars:string63;/63 个字符的 shortstring 字符串ch如类型1、delphi2007以前的编译器(包括delphi2007)缺省情况下认为char是ansichar类型, pchar pansichar 类型。2、delphi2009的编译器缺省情况下认为char是widechar类型,pchar是pwidechar类型。 请注意,没有任何方法可变更这个新的编译器预设设定。对于字符串类型而言,会以固定的 硕式编码方式将char类型对应到特定的数据类型。ansistring 类型1、ansistring是生存期自管理类型。2、an

5、sistring字符串总是以null字符结束的,这使得ansistring字符串能与win32api中的 字符串兼容。3、ansistring类型是一个指向在堆栈中的字符串结构的指针。口j以使用sizeof去读取ansistring类型的大小,不论字符巾的实际长度是多少,sizeof(astring) 永远是4。4、ansistring字符串在内存中分配的情况注意:在delphi?.0以后版本中,不能再通过字符串的第0个元素來设置或得到字符串的长度,只 能通过length()函数来得到字符串的长度,通过setlengthoil稈来设置字符串的长度。 borland并不保证string的内存结构

6、在以后的delphi版木中会保持不变。(1) 、delphi5内存结构如卜:(2) 、delphi7内存结构如下:ansistring指向一块内存起始偏移8字节处,前而8字节依次为引用计数和长度计数两个整 数。(3) 、delphi2009内存结构如下:-12-108-4最后一位字码页字符大小引川计数字串长度字串内容0除了字串长度及引川计数外,新的ansistring格式包括字符人小及字码页。字符人小可用来 区分ansistring及unicodestring,而字码页特别适用于ansistring类型(可用于delphi 2009), unicodestring类型的字码页则固定为1200,

7、字码包括utf8、gbk等,例如“$03a8 就是 936,查 msdn 936 - gb2312”。5、ansistring字符串的引用计数机制。(1) 、ansistring字符串基于引用计数机制,通过引用计数追踪内存中引用同一字符串的字 符串变量。(2) 、编译器生成的代码会在操作一个ansistring字符串前把引用计数+1,操作结束灰引用 计数1,如果引用计数=0时就自动释放整块内存。(3) 、ansistring字符串的复制在拷贝字符串的时候,object pascal并不是把字符串简单的复制一份,而是采取了引用计数 的方法,将两个字符串指向同一个内存空间,同吋引用计数加1。当字符

8、串变量被清除的吋 候,引用计数减1。通过ansistring字符串的引用计数机制,儿个字符串都能指向相同的物 理地址。因此,复制字符串仅仅是复制了指针而不是复制实际的字符串。(4) > ansistring字符串作为参数用拷贝方式(值参)传递ansistring字符宙会引起副作用,因为函数执行过程中会产牛一个对 字符串的额外引用;与此相反,通过引用(var)或常量(const)参数传递不会产生这种情 况。6、ansistring字符串的赋值。(1) 、将string赋值给另一个string,只是一个简单的指针赋值,不产生copy动作,只是增 加string的引用计数;(2) 、将一个pc

9、har变量类型赋值给一个string变量类型会产牛真正的copy动作,即将pchar 所指向的字符串整个copy到为string分配的内存中;(3) 、将string赋值给一个pchar变量类型,只是简单地将string的指针值赋值给pchar变 量类型,而stri隅的引用计数并不凶此操作而发生变化。因为这种情况pchar会对string产 生依赖,当stri隅的引用计数为零自动释放内存空间后,pchar很可能指向一个无效的内存 地址,在你的程序你必须小心对付这种情况。(3)、更新前拷贝机制(copyonwrite)在给字符串赋值的时候,object pascal首先会检杳字符串的引用计数是否

10、为1。如果是,按 照一般的方法直接赋值即可;否则,就说明有两个以上字符串指向同一个地址,这种情况就 复杂多了。object pascal使用的是“更新前拷贝机制(copy-on-write)”,为当前字符申另外 开辟一个缓冲区,将新内容拷入;同时,原来的字符串引川计数要减1。注意,一个字符串要等到修改结束,才释放一个引用并分配一个物理字符串。vars1,s2: string;begin给si赋值,si的引用计数为1s1 'andnowforsomething.*;s2:=s1;现在s2与si指向同一个字符串,s1的引用计数为2/s2现在改变了,所以它被复制到自c的物理空间,并且s1的引

11、用计数减1s2:=s2+'completelydifferentr;end;7、ansistring字符串的长度。(1) 、ansistring字符串的最大长度可以到2gb(2) 、ansistring字符串的初始长度第一次声明ansistring吋,它是没有长度的,凶此在字符串中就没有为字符分配空间。为了 对字符串分配空间,用一行字母或另一个字符串对它进行赋值,或者用setlengthoil程。(3) 、ansistring字符串的内存分配如果你要增加字符串的长度,而该字符串邻近乂没有空闲的内存,即在同一存储单元字符串 已没有扩展的余地,这时字符申必须被完整地拷贝到另一个存储单元。当

12、这种情况发牛时, delphi运行时间支持程序会以完全透明的方式为字符串重新分配内存。(4) 、setlength 方法为了有效地分配所需的存储空间,你可以川setlength过程设定字符串的最大长度值“sctlength(s(ringl,200);”。setlength过程只是完成一个内存请求,并没有实际分配内存。 它只是把将来所需的内存预留出来,实际上并没有使用这段内存。注意:代码中用setlength函数为字符串分配内存,假如内存分配失败,那么程序就会崩溃。8、ansistring字符串的内容访问。能像数组一样对字符串进行索引,但注意索引不要超出字符串的长度。vars:string;be

13、ginsetlength(sj);s1:=x;现在s有足够空间来容纳字符end;9、ansistring字符串的类型转换。(1)、将一个字符串转换为pchar类型时要小心,因为字符串在超出其作用范围时冇自动冋 收的功能,因此当进行p:=pchar(str)的赋值时,p的作用域(生存期)应当人于str的作用域。(2)、字符串a/ pchar z间的转换。可以把ansistring强制类型转换为pchar。如果要把pchar 的内容复制到ansistring,直接用赋值语句:stringvar:=pcharvar;(3)、使h pchar转换ansistring吋,会丢失ansistring的动态

14、增长和引用计数的功能,所 以一定耍小心,另外耍注意pchar长度的计算和字符串长度一定耍同步,否则会出问题。shortstring 类型1、shortstring在内存中分配的情况在内存中,字符串就像是一个字符数组,在字符串的第0个元索中存放了字符串的长度,紧 跟在后的字符就是字符串本身。2、shortstring字符串的最大长度(i ) shortstring缺省的最大长度为256个字节,这表示在shortstring中不能有大于255 个字符(1个长度字节+255个字符=256)o相对于ansistring来说,用shortstring是相当随意 的,因为编译器会根据需要为它分配空间。(2

15、)、能j shon类型限定符和一个长度限制来为shortstring分配小于256个字节的空间。 vars:string45;/45 个字符的 shortstring 字符串(3)、不要存放比分配给字符串的空间长度更长的字符。如果声明了一个变量是string8,并试图对这个变量赋值为'aprettydarrilong-string',这 个字符审将被截収为仅有8个字符,就要丢失数据。(5) 、shortstring字符串的内容访问。可以用数组的下标来访问shortstring中的字符。注意:当用数组的下标來访问shortstring中的一个特定宁符时,如果下标的索引值大于sho

16、rtstring 的实际长度,则会得到假的结杲或造成内存混乱。可以在project options对话框中选中range checking ®选框,这样编译器会白动加上特殊 的逻辑在运行吋捕捉此类错误。提示,虽然在程序中包括范围检查能发现字符串错误,但范 i韦i检查多少都影响应用程序的性能。通常使用的方法是在开发程序或调试程序的阶段用范i韦i 检查,而在确信程序稳定时,去掉范围检杳。3、shortstring跟以null结尾的字符串不兼容,因此使用shortstring调用win32函数时,必 须进行类型转换。widestring 类型1、widestring类型是生存期自管理类型。

17、2、widestring和ansistring的不同主要在三个方而:widestring由widechar字符组成,而不是由ansichar字符组成的,它们跟unicode字符 串兼容。widestring用sysallocstrlen()api函数进行分配,它们跟ole的bstr字符串相兼容。widestring没有引用计数,所以将一个widestring字符串赋值给另一个widestring字符串 吋,就需要从内存中的一个位置复制到另一个位置。这使得widestring在速度和内存的利用 上不如ansistring有效。3、widestring在内存中分配的情况widestring同样是用

18、4个字节来存储字符串长度,但是它每个元索的人小是2个字节。4、widestring字符串的类型转换编译器自动在ansistring类型和widestring类型的变量间进行转换。5、widestring字符串的内容访问。能川数组的卜标来访问widestring中的字符。pansichar 类型1、pansichar 类型pansichar被定义成一个指向以null(零)结束的字符串的指针,它的人小只有32位,定义时 由delphi自动填0。因为pansichar是指针,所以它能指向任何地方(也就是说它不一定非 要指向字符串不可)。2、pansichar 7符串pansichar型字符串由#0表

19、示字符串结尾。delphi所提供的相关pchar字符串的操作都是判 断#0来决定字符串的结尾的。3、pansichar字符串的内存要将pchar作为字符串使用的话必须口己分配内存用完必须口己释放。4、pansichar字符串的长度pchar字符串的理论最大长度是4gbo5、pansichar字符串在内存中的分布情况。6、pansichar类型转换(1 )在大多数情况下,ansi string类型能被用成pansichar。(2) 、把一个string赋值给pansichar只是将string屮保存具体字符串的内存的地址给 pansichar 变量。(3) 、可以把ansichar数组第一个元素

20、的地址给pansichar。char数纽1、char数组也是指向字符串的指针。2、char数组与pchar的区别(1) 、char数组(均指非动态数组)一旦定义好,它的长度就固定了。(2) 、char数组的地址是常量,不能另赋其它值。3、char数组的使用char数组使用的比较少了,因为多数可以用char数组的地方,现在比较流行的作法是定义 一个ansistring,再用setlength來设定它的长度。以null结束的字符串1、一个零终止串是一个字符序列,该序列以一个零字节(或null)结尾。零终止串在delphi 中可川下标从零开始的字符数组表示,c语言就是川这种数组类型定义字符串,因此零

21、终止 字符数组在windowsapi函数(基于c语言)中很常见。由于pascal长字符串与c语言的 零终止字符串完全兼容,因此当需要把字符串传递给windows api函数时,你可以直接把长 字符串映射为pchar类型。2、delphi有三种不同的以null结束的字符串类型:pchar、pansichar和pwidechar。它们 都是由delphi的三种不同字符组成的。这三种类型在总体上跟pchar是一致的。警告,win32api函数需要以null结尾的字符串,不要把shortstring字符串传递给api函数, 因为编译器将报错,长字符串可以传递给win32api函数。string、pch

22、ar 和 chai数组比较1、占用的内存大小char数组<pchar(指分配过字符串的)<s(ring(除了具体字符串外还包含字符串长度);如果 空字符串那么 pchar<string<array o.nj of char;2、处理效率从速度來说毫无疑问string最慢,例如:作为参数传递(非vat调用时)给过程时string将整个 字串的副本传递过去,pchai将指针本身的副本传递过去(32位),char数组和pch如一-样,传 递的是第一个元索的地址副木o不过就灵活性来说string最高,而且delphi支持的函数故多.另外门j以将string作为buffer 使用

23、(因为它当中可以包含字符0)o如果涉及到windows api或混合编程等,接口部分一般使用pcharo附件资料示例:string类型说明:iij以使用编译开关$日來将string类型定义为shortstring,当$14编译开关的值为负时,string 变量是shortstring类型;当$日编译开关的值为正时(缺省情况),字符串变量是ansistring 类型。使用$h规则的一个例外是,如杲在定义时特地指定了长度(最大在255个字符内),那么总 是 shortstringc代码:procedure tfonn 1.button 1 click(sender: tobject);var$h-

24、jsi: string; /s1 是 shortstring 类型$h+s2: string; /s2 是 ansistring 类型beginshowmessage(inttostr(sizeof(s2); /4 字节end;procedure tform i.button 1 click(sender: tobject);vars: string63; /63 个字符的 shortstring 字符串beginshowmessage(inttostr(sizeof(s);end;示例:shortstring的长度说明:能用short类型限定符和一个长度限制来为shortstring分配小于

25、256个字节的空间。不要存 放比分配给字符串的空间长度更长的字符,如果声明了一个变量是string81,并试图对这个 变量赋值为a_pretty_darn_long_string这个字符串将被截取为仅有8个字符,就要丢失 数据。代码:procedure tform 1 .button 1 click(sender: tobject);vars: string4j; /4 个字符的 shortstring 字符串begins ±123456;showniessage(inttostr(length(s); 长度 4end;procedure tform 1 .button 1 clic

26、k(sender: tobject); vars: string4;begins := 421;showmessage(inttostr(length(s); 长度 2 仏一s := '1234567&showmessage(inttostr(length(s); 长度 4 end;procedure tform 1.button 1 click(sender: tobject); vars: string45;begins := '123456'showmessage(inttostr(length(s); 长度 6/s:=,12345678,;end;示例:

27、shortstring越界访问说明:当用数组的下标来访问shortstring中的一个特定字符时,如果下标的索引值大于声明时 shortstring的长度,则会得到假的结果或造成内存混乱。代码:procedure tfomi 1.button 1 click(sender: tobject);vars:shortstring;begins:=】23;showmessage(s4);end;示例:widestring类型转换说明:编译器自动在ansistring类型和widestring类型的变量间迓行转换。代码:procedure tfoim i.button 1 click(sender:

28、tobject);w: widestring:s: string;beginw := ,margaritaville,;s := w; /widestring 转换成 ansistrings := omemonday1;w := s; /ansistring 转换成 widestring示例:windows api函数调用说明:由于string与c语言的零终止字符串完全兼容,因此当需要把字符串传递给windows api函数时,你可以直接把长字符串映射为pchar类型。代码:procedure tform i.button 1 click(sender: tobject);varsi: str

29、ing;beginsetlength(s 1,100);getwindowtext(handle,pchar(sl),length(sl);button 1 .caption := s1;end;示例:winapi函数调用说明:使川pchar转换string的同时也就丢失了 string的动态增长和引川计数的功能,所以一定要 小心,另外要注意pchar长度的计算和字符中长度一定要同步,否则会出问题。代码:程序编译通过,但执行结果会令你惊讶,因为按钮的标题并没变,所加的常量字符串没有添 加到按钮标题中。问题原因是setlength将字符串长度设成了 256,而pchar计算的长度只 到第一个$0

30、为止,此吋delphi仍可以正常输出字符串,并能通过零终止符判断字符串何吋 结束,但是如果你在零终止符后添加更多的字符,那么这些字符将被忽略。解决的办法是重 新设置字符串的长度。procedure tformi.button 1 click(sender: tobject);varsi: string;beginsetlength(s 1,100);getwindowtext( handle,pchar(s l),length(s 1);si := si + ' is the title1; / this won't workbutton 1 .caption := si;en

31、d;procedure tfonn 1 .button 1 click(sender: tobject);varsi: string;beginsetlength(s 1,100);getwindowtext(handle,pchar(s l),length(sl);si :=pchar(sl);/setlength (si, strlen (pchar (si);si := si + 1 is the title1;button 1 .caption := s1;end;刀;例:shortstring与pchar的类型转换说明:使用指向字符串的指针,如果不是以0结尾,运行时就会出现错误。为了

32、避免这种错误,需要在 字符串结尾人工加入0即char(o),或用strpcopy函数在字符串结尾自动加0。代码:procedure tfonn 1.button 1 click(sender: tobject);vars: shortstring;p: pchar;begins := 'new' s0=3 slj='n' s2j=,e, s3='w'p := sl; 不是以0结尾,莫用pchar型指针button 1 .caption := stipas(p); 运行时出现错误end;procedure tform 1.button 1 ciic

33、k(sender: tobject); vars: shortstring;p: pchar;begins := 'new* + char(o); 以 0结尾,可用 pchar型扌旨针 s0=4 sl=,n, s2j=,e, s二w s4=0;button 1 .caption := stipas(p);end;示例:delphi5字符串内存结构代码:procedure tform 1 .button 1 click(sender: tobject);typepstrrec = astrrec;strrec = packed recordallocsiz: longint;refcnt: longint;length: longint;end;varstr: string;p: pstrrec;beginstr :='123:p := pointer(integer(st

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论