关于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;
显示结果如下:


关于字符串就先浅浅的谈到这个,以后再深入了解。
********************************************************************
Delphi字符串、PChar与字符数组之间的转换
关于Delphi中的字符串的详细分析的更多相关文章
- 关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)
关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short ...
- 内核中container_of宏的详细分析【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...
- Delphi 中的字符串(还解释了shortstring)good
一.Delphi 2009 之前的字符串(不支持 Unicode): Delphi 2009 之前的字符串分为 3 种:ShortString.AnsiString.WideString. [Shor ...
- javascrip中cookie的使用详细分析
JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求. cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由J ...
- js中cookie的使用详细分析
JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求. cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由J ...
- 转:js中cookie的使用详细分析
cookie机制将信息存储于用户硬盘,因此可以作为全局变量,这是它最大的一个优点.它可以用于以下几种场合. (1)保存用户登录状态.例如将用户id存储于一个cookie内,这样当用户下次访问该页面时就 ...
- Delphi中常用字符串处理函数
.copy(str,pos,num) 从str字符串的pos处开始,截取num个字符的串返回. 假设str为,)=,)='def' .concat(str1,str2{,strn}) 把各自变量连接起 ...
- 二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析
1.计算机二进制系统中最小单位bit 在计算机二进制系统中: bit (位) :数据存储的最小单元. 简记为b,也称为比特(bit),每个二进制数字0或1就是一个位(bit),其中,每 8bit = ...
- Java中的<< 和 >> 和 >>> 详细分析
<<表示左移移,不分正负数,低位补0: 注:以下数据类型默认为byte-8位 左移时不管正负,低位补0 正数:r = 20 << 2 20的二进制补码:0001 0100 向左 ...
随机推荐
- TPCx-BB官宣最新世界纪录,阿里巴巴计算力持续突破
2019年9月17日,TPC官宣Alibaba Cloud MaxCompute认证结果.同月26日,杭州云栖大会阿里巴巴宣布了这一成绩,飞天大数据平台计算引擎MaxCompute成为全球首个TPCx ...
- SCOI 2014 省选总结
总的来说作为高一党,去做省选难度的题完全就是去玩的,还是找惯例起身跪hja. 跪毕,看看自己惨不忍睹的成绩,我只想说:电子坑大为什么day1的暴力只有10分!为什么呢?我笑看题面: 方伯伯种玉米,方伯 ...
- NX二次开发-UFUN CSYS坐标系转换UF_CSYS_map_point
1 NX9+VS2012 2 3 #include <uf.h> 4 #include <uf_curve.h> 5 #include <uf_csys.h> 6 ...
- 微信-小程序-开发文档-服务端-模板消息:templateMessage.deleteTemplate
ylbtech-微信-小程序-开发文档-服务端-模板消息:templateMessage.deleteTemplate 1.返回顶部 1. templateMessage.deleteTemplate ...
- sklearn中回归器性能评估方法
explained_variance_score() mean_absolute_error() mean_squared_error() r2_score() 以上四个函数的相同点: 这些函数都有一 ...
- Lunascape:将FireFox、Safari和IE合为一体的浏览器
转自:http://blog.bingo929.com/lunascape-firefox-safari-ie-all-in-one.html 作为前端开发/网页设计师,电脑中总是安装着各种不同内核渲 ...
- Visual Studio 2010 启动调试报错 “访问OLE注册表的错误”
错误:访问OLE注册表的错误(异常来自HRESULT:0x8002801C(TYPE_E_REGISTRYACCESS)) 很简单,其实只要 “以管理员身份运行” Visual Studio即可.
- 基于第三方开源库的OPC服务器开发指南(1)——OPC与DCOM
事儿太多,好多事情并不以我的意志为转移,原想沉下心好好研究.学习图像识别,继续丰富我的机器视觉库,并继续<机器视觉及图像处理系列>博文的更新,但计划没有变化快,好多项目要完成,只好耽搁下来 ...
- Java oop创建自定义异常
package com.test; /** *不管是在方法定义时就使用try catch,还是在定义方法时将异常抛出在调用方法时使用try catch都能达到效果 * */public class M ...
- iOS开发系列-支付宝支付
概述 开发中支付通常都会集成支付宝支付,下面讲解支付宝的整体流程. 集成支付宝支付的流程 签约 与支付签约,得到获取商户的ID(partner).账户ID(seller).私钥privateKey. ...