关于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. SUSAN检测算子

    USAN区域(核同值区):和核像素的灰度相同会相信的模板像素的区域. 利用这个区域的尺寸.重心.二阶矩等可以帮助检测图像的边缘和角点.利用USAN的面积作为特征可以起到增强边缘和角点的效果. 该方法不 ...

  2. 改ucosii的中断禁止和恢复代码,这是一个荒谬的错误【 mrs msr】

    ucosii原来的禁止中断以及恢复中断的代码是最简的,但是使用之前,必须声明一个固定名为 OS_CPU_SR   cpu_sr 的变量,吊在那里感觉很怪. ;********************* ...

  3. 10 - 应用程序间通信、本地通知、加速计、URL传输中文

    一.应用间通信 URL 调用系统服务: tel:11111 sms:xxx@163.com http:// URL深入 类型://主机:端口/地址?参数 label框等于文字大小快捷键:command ...

  4. netbeans 将项目打包生成单个可执行的 jar

    原文:netbeans 打包生成 jar 文件页里找到build.xml文件,打开在</project>前 加入以下代码保存之 <target name="package- ...

  5. android中关于ListView的卡位说明

    需求:做项目的时候,需要将ListView的header的一个Tab卡位,即listView滑动后,Header的某一个部分可以定在ListView的顶端卡住. 解决的方案:监听ListView的滑动 ...

  6. CentOS桌面环境如何打开终端以及如何将终端加入右键

    安装完CentOS的桌面环境后,默认在桌面以及右键是没有打开终端选项的,要想打开终端,可以由以下步骤: 在左上角菜单[Applications]--->[System Tools]---> ...

  7. Ch05 视图模型

    5.1  什么是视图模型 5.1.1  在线商店示例 5.1.2  建立视图模型 5.1.3  交付表现模型 5.1.4  ViewData.Model 5.2  表现用户输入 5.2.1  设计(输 ...

  8. java BigDecimal的使用和四舍五入及格式规范(精准数据)

    • Java中的简单浮点数类型float和double不能够进行运算.不光是Java,在其它很多编程语言中也有这样的问题. 如果我们编译运行下面这个程序会看到什么? public   class  T ...

  9. hihocoder1302 最长回文子串

    hihocoder1302 最长回文子串 先贴代码 所有的上面的提示已经交代的好清楚了…… #include <iostream> #include <cstring> #in ...

  10. codeforces 148D 概率DP

    题意: 原来袋子里有w仅仅白鼠和b仅仅黑鼠 龙和王妃轮流从袋子里抓老鼠. 谁先抓到白色老师谁就赢. 王妃每次抓一仅仅老鼠,龙每次抓完一仅仅老鼠之后会有一仅仅老鼠跑出来. 每次抓老鼠和跑出来的老鼠都是随 ...