关于Delphi中的字符串的浅析

来源:互联网 发布:广东高职高考网络视频 编辑:程序博客网 时间:2024/05/16 06:24

======================================================
注:本文源代码点此下载
======================================================

只是浅浅的解析下,让大家可以快速的理解字符串。

其中的所有代码均在delphi7下测试通过。

delphi 4,5,6,7中有字符串类型包括了:

短字符串(short string)

长字符串(long string)

宽字符串(wide string)

零结尾字符串(null-terminated string)、pchar和字符数组

1、短字符串(short string)

固定长度,最大字符数个数为255,短字符串也成为长度字节(length-byte)字符串,这时因为短字符串的第0个元素包含了这个字符串的长度(字符串中字符的个数)。因此shortstring的缺省最大长度为256个字节(255个字符+1个长度字节=256),声明一个短字符串有两种方式,如下:

var

s: shortstring;{ 255个字符长度,256个字节}

s1: string[255];{ s1和s的字符类型一样}

len: integer;

begin

s := 'hello';

len := ord(s[0]); { len现在包含s的长度为5,ord函数可以把一个字符类型转换为整数类型}

len := sizeof(s); { len现在包含的是shortstring类型的大小,为256字节}

end;

以上例子通过s[0]可以获得s的字符串长度,当然也可以用length函数来确定一个短字符串的长度。

可以通过数组的下标来访问shortstring中的一个特定位置的字符,具体使用参看下面例子和注释说明:

var

s: string[8];

i: integer;

begin

s := 'a_pretty_darn_long_string';

{ 因为s只有8个字符大小,

因此s的实际存储的内容为“a_pretty”}

i := 10;

s[i] := 's';

{ 因为s只有8个字符大小,

试图改写第10个元素,将会使内存混乱}

end;

2、长字符串(long string)

长字符串 (ansistring)是一种动态分配的字符串,其大小只受可用内存的限制。声明一个长字符串,只需要用关键字string不加大小参数即可。

在delphi 7中ansistring包含的字符是用单字节存储的。

var

s: string;

由于是动态分配的,一次可以随意修改字符串,而不用担心对其他的影响,也不用担心越界的问题。string类型没有0元素,试图存取string类型的0元素会产生一个编译错误。

通过length函数也可以获得长字符串的长度,也可以通过setlength过程为长字符串设置长度。其在内存中分配情况如下:

3、宽字符串(wide string)

宽字符串和长字符串一样,大小只受有效内存的限制,并实行动态分配。

在delphi 7 中widestring被实现为2个字节存储一个字符,用widestring来处理多字节字符是十分方便的。如:

var

s: string;

{ 在delphi 7中默认string等同于ansistring}

ws: widestring;

begin

s := '世界你好';

ws := s;

showmessage(s[1]);{ 此时无任何显示,因为s[1]取出的是‘世’的一半}

showmessage(ws[1]); { 显示‘世’}

end;

4、零结尾字符串(null-terminated string)、pchar和字符数组

在c和c++中没有真正的字符串数据类型,都是通过以null结尾(0)的字符数组来实现的,字符数组没有长度字节,因此只能通过结尾的null标志来作为字符串的字符结束标志。又因为windows是用c编写的,很多windows函数要用到以字符数组作为参数,但pascal字符串类型不是字符数组,因为为了让pascal字符串也能与windows兼容,就需要一个字符串数组,pchar类型正是符合这种需求,在任何需要字符数组的地方都可用pchar。

虽然ansistring和widestring都已经实现了null

相应的也有pansichar和pwidechar,分别对应于ansichar字符和widechar字符。

例如:windows messagebox函数,此函数声明如下:

function messagebox(hwnd: hwnd; lptext, lpcaption: pchar; utype: uint): integer; stdcall;

第二个和第三个参数需要一个指向字符数组的指针,为了可以调用此函数,有以下三种方法来实现

1、pchar()类型转换

var

text: string;

caption: string;

begin

text := 'this is a test.';

caption := 'test message';

messagebox(0, pchar(text), pchar(caption), 0);

{ 这里pchar用来把string类型转换为null结尾的字符串}

end;

其中

2、pchar变量

我们先做一个实现,看看pchar类型到底是啥呢?

运行下面程序:

var

text: pchar;{ 声明为pchar类型}

str: string;{ 声明为string类型}

begin

text := 'this is a test.';{ 都被赋予了相同的字符串}

str := 'this is a test.';

showmessage(inttostr(sizeof(text)));{ 4字节,实质是指针}

showmessage(inttostr(sizeof(str)));{ 也是4字节,也是指针}

end;

通过上面的程序,我们知道text只不过是一个指针而已。

var

text: pchar;

begin

text := 'this is a test.';

messagebox(0, text, 'test message', 0);

{ 这里text直接声明为了pchar类型,字符串常量可以直接用}

end;

指针text指向了这样一个内存区域,一个包含null的结尾的’this is a test’字符串的区域。其等同于下面的代码:

const

tempstring: array[0..15] of char = 'this is a test.'#0;

var

text: pchar;

begin

text := @tempstring[0];

{text指向null结尾的tempstring字符数组的第0个元素的地址,

也就是整个字符数组的首地址}

messagebox(0, text, 'test message', 0);

end;

3、char类型字符数组

最有还可以用char数组来代替pchar,代码如下:

var

text1: array[0..14] of char;{ 大小为15个字符}

text2: array[0..20] of char;{ 大小为21个字符}

begin

text1 := 'this is a test.';{text1和text2的字符长度都为15个字符}

text2 := 'this is a test.';

messagebox(0, text1, 'test message 1', 0);

{因为text1的字符长度超过了其声明的大小,因为会内存访问混乱,显示换乱}

messagebox(0, text2, 'test message 2', 0);

{text2的字符长度比起声明的大小要小,因为正常访问,显示正确}

end;

显示结果如下:

关于字符串就先浅浅的谈到这个,以后再深入了解。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击