在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
字符串类型 Delphi有三种类型的字符: ●AnsiChar这是标准的1字节的ANSI字符,程序员都对它比较熟悉。 ●WideChar这是2字节的Unicode字符。 ●Char在目前Delphi早前的版本相当于AnsiChar,但在Delphi以后版本中相当于WideChar. 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 个字节} {如果不超出 #255 的范围是可以直接赋值的} c := 'B'; ShowMessage(c); {万} end; 记住因为一个字符在长度上并不表示一个字节,所以不能在应用程序中对字符长度进行硬编码,而应该使用Sizeof()函数。注意Sizeof()标准函数返回类型或实例的字节长度。 字符串是代表一组字符的变量类型,Delphi有下列几种不同的字符串类型来满足程序的要求: ●AnsiString这是Pascal缺省的字符串类型(string),它由AnsiChar字符组成,其长度没有限制,同时与null结束的字符串相兼容。 ●ShortString保留该类型是为了向后兼容Delphi1.0,它的长度限制在255个字符内。 ●WideString功能上类似于AnsiString,但它是由WideChar字符组成的。 ●PChar指向null结束的Char字符串的指针,类似于C的char*或lpstr类型。 ●PAnsiChar指向null结束的AnsiChar字符串的指针。 ●PWideChar指向null结束的WideChar字符串的指针。 1.AnsiString类型 AnsiString(或长字符串)类型是在Delphi2.0开始引入的,因为Delphi1.0的用户特别需要一个容易使用而且没有255个字符限制的字符串类型,而AnsiString正好能满足这些要求。 虽然AnsiString在外表上跟以前的字符串类型几乎相同,但它是动态分配的并有自动回收功能,正是因为这个功能AnsiString有时被称为生存期自管理类型。ObjectPascal能根据需要为字符串分配空间,所以不用像在C/C++中所担心的为中间结果分配缓冲区。实际上,AnsiString类型是一个指向在堆栈中的字符串结构的指针。 AnsiString字符串类型有引用计数的功能,这表示几个字符串都能指向相同的物理地址。因此,复制字符串因为仅仅是复制了指针而不是复制实际的字符串而变得非常快。当两个或更多的AnsiString类型共享一个指向相同物理地址的引用时,Delphi内存管理使用了copy-on-write技术,一个字符串要等到修改结束,才释放一个引用并分配一个物理字符串。当我们声明一个AnsiString变量时,它是没有长度的,因此字符串没有为字符申请内存空间。为了申请字符串的内存空间,我们可以给它赋值为一行字符或者另一个字符串变量,也可以使用SetLength()函数。 var str: string; s: string; begin str := 'delphi'; s[1] := 'd';//错误,s此时还没有申请内存空间。 s := 'delphi'; //或者s := str; 或者SetLength(s, 4); end; AnsiString字符串总是null结束的,这就使得调用Win32API函数或其他需要PChar型字符串的函数变得容易了。只要把一个字符类型强制转换为PChar类型。我们在调用时进行强制类型转换PChar(s),或者@s[1]。(s[1]是字符串s的第一个字符,@是取地址。s[0]存放的是字符串s的长度)。下面的代码演示了怎样调用Win32的GetWindowsDirectory()函数,这个函数需要一个PChar类型的参数: var S:String; begin SetLength(S,256);//重要!首先给字符串分配空间 //调用API函数,S现在包含目录字符串 GetWindowsDirectory(PChar(S),256); 如果使用了将AnsiString字符串强制转换为PChar类型的函数和过程,在使用结束后,要手工把它的长度恢复为原来以null结束的长度。STRUTILS单元中的RealizeLenght()函数可以实现这一点: procedure RealizeLength(varS:string); begin SetLength(S,StrLen(PChar(S))); end; 调用ReallizeLength(): var S:string; begin SetLength(S,256);//重要!首先给字符串分配空间 //调用函数,S现在包含目录字符串 GetWindowDirectory(PChar(S),256); RealizeLength(S);//设置S的长度为null结束的长度 end; 2. ShortString类型 ShortString类型跟以null结尾的字符串不兼容,正因为这样,用ShortString调用Win32函数时,要做一些工作。下面这个ShortStringAsPChar()函数是在STRUTILS.PAS单元中定义的。 function ShortStringAsPChar(varS:ShortString): PChar; {这函数能使一个字符串以null结尾,这样就能传递给需要PChar类型参数的Win32API函数,如果字符串超过254个字符,多出的部分将被截掉} begin if Length(S)=High(S) then Dec(S[0]); {如果S太长,就截取一部分} S[Ord(Length(S))+1]:=#0;{把null加到字符串的最后} Result:=@S[1];{返回PChar化的字符串} end; Win32API函数需要以null结尾的字符串,不要把ShortString字符串传递给API函数,因为编译器将报错,长字符串可以传递给Win32API函数。 3.WideString类型 WideString类型像AnsiString一样是生存期自管理类型,它们都能动态分配、自动回收并且彼此能相互兼容,不过WideString和AnsiString的不同主要在三个方面: ●WideString由WideChar字符组成,而不是由AnsiChar字符组成的,它们跟Unicode字符串兼容。 ●WideString用SysAllocStrLen()API函数进行分配,它们跟OLE的BSTR字符串相兼容。 ●WideString没有引用计数,所以将一个WideString字符串赋值给另一个WideString字符串时,就需要从内存中的一个位置复制到另一个位置。这使得WideString在速度和内存的利用上不如AnsiString有效。 就像上面所提到的,编译器自动在AnsiString类型和WideString类型的变量间进行转换。示例如下: var W:wideString; S:string; begin W:='Margaritaville'; S:=W;//wideString转换成AnsiString S:='ComeMonday'; W:=S;//AnsiString转换成WideString end; 为了能灵活地运用WideString类型,ObjectPascal重载了Concat()、Copy、Insert()、Length()、Pos()和SetLength()等例程以及+、=和<>等运算符。就像AnsiString和ShortString类型一样,能用数组的下标来访问WideString中一个特定的字符。 4.字符串指针 Delphi有三种不同的以null结束的字符串类型:PChar、PAnsiChar和PWideChar。它们都是由Delphi的三种不同字符组成的。这三种类型在总体上跟PChar是一致的。PChar之所以保留是为了跟Delphi1.0和Win32API兼容,而它们需要使用以null结束的字符串,PChar被定义成一个指向以null(零)结束的字符串指针与AnsiString和WideString类型不同,PChar的内存不是由ObjectPascal自动产生和管理的,要用Object Pascal的内存管理函数来为PChar所指向的内存进行分配。PChar字符串的理论最大长度是4GB。 在大多数情况下,AnsiString类型能被用成PChar,应该尽可能地使用AnsiString,因为它对字符串内存的管理是自动,极大地减少了应用程序中内存混乱的错误代码,因此,要尽可能地避免用PChar类型以及对它相应进行人工分配内存。在Debug下开启内存泄漏: {$ifdef DEBUG} ReportMemoryLeaksOnShutDown := True; //插入到应用程序入口的begin语句下。 {$endif} 通常,用StrAlloc()函数为PChar缓冲区分配内存,但是其他几种函数也能用来为PChar类型分配函数,包括AllocMem()、GetMem()、StrNew()和VirtualAlloc()API函数。这些函数有相应的释放内存的函数。 var p: PChar; str: string; begin {可以给 PChar 直接赋予字符串常量} p := '中国'; ShowMessage(IntToStr(Length(p))); {4} {给变量值需要转换} str := '中国杭州'; p := PChar(str); {转换} ShowMessage(p); {中国杭州} ShowMessage(IntToStr(Length(p))); {8} end; //宽字符指针 PWideChar var p: PWideChar; str: WideString; {注意这里不是 String} begin {可以给 PWideChar 直接赋予字符串常量} p := '中国'; ShowMessage(IntToStr(Length(p))); {2} {给变量值需要转换} str := '中国杭州'; p := PWideChar(str); {转换} ShowMessage(p); {中国杭州} ShowMessage(IntToStr(Length(p))); {4} end; 数值型 整数型(Integer):整数型是整数的集合,包括多种不同的整数类别。
实数型(Real):实数型是实数的集合,包括多种不同的类型。Real类型只有在和以前Borland Pascal兼容的情况下才使用,否则应使用Double或Extended类型。
Delphi数据类型分类如下:
|
请发表评论