关于Delphi中的字符串的浅析

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

其中的所有代码均在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;

显示结果如下:

   

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

http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html

关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)的更多相关文章

  1. 关于Delphi中的字符串的详细分析

    关于Delphi中的字符串的详细分析   只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(S ...

  2. Delphi 中的字符串(还解释了shortstring)good

    一.Delphi 2009 之前的字符串(不支持 Unicode): Delphi 2009 之前的字符串分为 3 种:ShortString.AnsiString.WideString. [Shor ...

  3. Delphi中常用字符串处理函数

    .copy(str,pos,num) 从str字符串的pos处开始,截取num个字符的串返回. 假设str为,)=,)='def' .concat(str1,str2{,strn}) 把各自变量连接起 ...

  4. Delphi中String类型原理介绍

    Delphi中字符串的操作很简单,但幕后情况却相当复杂.Pascal传统的字符串操作方法与Windows不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型,该类型 ...

  5. delphi XE的字符串处理

    最近用delphi xe做了个东西,因为以前一直使用Delphi 7做开发,delphi 7 到delphi XE有了很大的变化,最大的变化就是对Unicode的支持,所以刚开始使用DELPHI XE ...

  6. Delphi中array of const应用

    Delphi的Format函数大家都用得很多,第二个参数用着确实很方便.最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Po ...

  7. Delphi中stringlist分割字符串的用法

    Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...

  8. Delphi中的各种字符串、String、PChar、Char数组

    参考博客:http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html 其中的所有代码均在Delphi7下测试通过. Delphi ...

  9. delphi 中字符串与16进制、10进制转换函数

      //字符串转成16进制代码function strToHexStr(str:string):string;varc:char;ss:string;i:integer;beginwhile str& ...

随机推荐

  1. OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决

    引言 之前,我们在讨论基于ORPSoC的ipcore设计时提到过DMA的问题,当时我们实现DMA的功能时,访问的是local memory,并没有使用主存(即外部的SDRAM),使用的是本地的一块存储 ...

  2. hibernate 一对多映射

    package com.entity.onetomany; import java.util.ArrayList; import java.util.List; import javax.persis ...

  3. awk 的逻辑运算字符

    既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算啰-例如底下这些:运算单元代表意义> 大于小于>= 大于或等于小于或等于== 等于!= 不等于值得注意的是那个 ...

  4. 软件project师的属性与发展

    工作近十年了.[软件project师] 一直是我职业 title 的中心词,仅仅是前面的修饰语在不断变化,从0基础.中级.高级到资深. 事实上 [软件project师] 是一个非常泛化的定义.工作现实 ...

  5. hdu1172猜数字

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1172 题目 猜数字 Time Limit: 20000/10000 MS (Java/Others) ...

  6. Android4.2以及最新SDK的尝鲜使用

    谷歌已经公布了Android4.2,而且也对应的更新了SDK到4.2.事实上最基本的是谷歌这次帮开发人员把eclipse.ADT.SDK整合 到了一起,我们仅仅须要下载一个ADT Boundle,就能 ...

  7. Android 它们的定义View它BounceProgressBar

    转载请注明出处:http://blog.csdn.net/bbld_/article/details/41246247 [Rocko's blog] 之前几天下载了非常久没用了的桌面版酷狗来用用的时候 ...

  8. 2014年国内经常使用移动client推送服务介绍和比較

    经过5年移动互联网的迅速发展,如今推送服务方面国内已经出现了非常多产品,比如极光推送,个推,一推,百度推送,友盟推送等,我们在选择推送服务时,首先排除了付费的推送服务,重点调查了免费的推送服务.   ...

  9. Join的实现步骤 以及连接的概念

    Join的实现步骤  以及连接的概念 我们常说连接有三种,即 交叉连接.内连接.外连接,这三者的概念很容易模糊,现在我们先放下概念,搞清楚完整连接实现的步骤: 一个完整的连接有三个步骤:.做笛卡儿积: ...

  10. 基于集合成工控机Ubuntu系统安装分区详解

    基于集合成工控机Ubuntu系统安装分区详解 硬件描述:双核的CPU,128G的固态硬盘 软件描述:使用Ubuntu12.04系统,内核3.8.0-29版本,QT4.8.1版本 1.新建分区表 /de ...