请问string,pchar,char数组的详细区别?--200分送上!

gigi2000 2000-09-19 11:45:00
请问Delphi中string类型,pchar类型,char数组的详细区别以及应用范围?
哪个读写速度更快,占用内存更少,效率更高...?
...全文
1388 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
gigi2000 2000-09-22
  • 打赏
  • 举报
回复
如果还有回答者,请不吝赐教!
我准备给分啦!
JGTM2000 2000-09-22
  • 打赏
  • 举报
回复
分数给了一半,看来还有不解之处喽?嘿嘿~~~~
JGTM2000 2000-09-22
  • 打赏
  • 举报
回复
To gigi2000: 如果还有什么困惑可以继续提出来,大家帮你解答。
To keboy, netsong: Thanks for your appreciation. :) I often check my mailbox @sina.com, so write to me if you need help. My pleasure. :)
netsong 2000-09-22
  • 打赏
  • 举报
回复
to JGTM2000:精,妙,好。
to gigi2000: 分数非JGTM2000莫属,加分吧。

TO JGTM2000: 您是不是常用JGTM2000@SINA.COM这个信箱?
flyby 2000-09-22
  • 打赏
  • 举报
回复
gigi2000
难道你还比明白吗
这么多人回答
我看已没什么可回答的了
keboy 2000-09-22
  • 打赏
  • 举报
回复
JGTM2000:
你老是不是在北京?真想跟你学学。
my e_mail : keboy@263.net
keboy 2000-09-22
  • 打赏
  • 举报
回复
JGTM2000:
佩服,佩服(事实上,如果你能充分的理解string,你就会赞叹Delphi的精妙了),精辟之极.
gigi2000,你再不给分,对不起他老人家了;
gigi2000 2000-09-21
  • 打赏
  • 举报
回复
如果还有回答者,请不吝赐教!
gigi2000 2000-09-20
  • 打赏
  • 举报
回复
我回去仔细体会一下,然后就给分,如果还有回答者,请不吝赐教!
JGTM2000 2000-09-20
  • 打赏
  • 举报
回复
char, array of char, PChar都是简单类型,简单类型当然通用性好,这个很容易理解,只要保证内存布局一样就可以了,在这个前提下如果有必要可以采取手段欺骗编译器的强类型检查。Delphi为什么提出string类型?肯定有它的道理。什么道理?用C的同志们都知道处理什么类型都没有处理字串类型费劲,Delphi作为如此优秀的RAD工具自然要想办法解决这个问题。事实上,如果你能充分的理解string,你就会赞叹Delphi的精妙了。

处理字串时候最恼人的问题之一就是内存的分配与释放,如果你用char数组(array [0..l] of char等同于C中的char[l+1]),则内存被静态分配,这种情况主要用在定宽字符串中。但是对于最常见的变长字串可就费劲了。string解决这个问题的手段是,由编译器通过引用计数和长度信息自动维护字串内存区域。事实上,当把一个string类型的变量当成字符指针看的时候,他的内存布局是这样的:

s: string = 'CSDN';
则有PChar(s)^ = 'C',(PChar(s)+1)^='S',……(PChar(s)+4)^=#0。
且:PInteger(Integer(Pointer(s))-1*sizeof(DWORD))^=length(s)
和:PInteger(Integer(Pointer(s))-2*sizeof(DWORD))^=refcount(s)

可视化一下就是:
[RefCount: DWORD][Length: DWORD]^['C']['S']['D']['N'][#0]
(^处即为s所指内存地址)

可以看到string在s之后的内存布局同PChar完全一致,都是ASCIIZ标准的字串,因此任何string类型的变量都可以通过强制类型转换的语法欺骗编译器的强类型检查而作为PChar直接使用,如: PChar(s)。而且由于字串的长度存放在偏移-4处,因此求字串长度的时候速度极快,因为length(s) = PInteger(Integer(Pointer(s))-4)^,不用像PChar和array那样从头数到尾直到#0。那引用计数是干哈的呢?首先要明确一点,Delphi对于string是从堆中自动分配和释放内存,分配好说,但是什么时候释放呢?如果你了解COM的引用计数原理就知道,通过维护refCount系统就能够确定可以安全释放对象的时机了。因为Delphi对于string类型的字串使用了copy-on-write技术,因此如果简单的两个string都包含相同的内容,则实际上内存中仅有一份拷贝。如:
s1 := 'I love Delphi'; // line 1
s2 := s1; // line 2
s1 := s1 + '!'; // line 3
在第一行,Delphi将为s1分配内存并设定好负偏移处的长度信息与引用计数(初始为1);在第二行,事实上没有任何的内存分配操作,s2简单的被赋予s1的指针信息,同时他们指向的字串的引用计数+1(事实上Delphi程序内部还有一张表来记录这些引用信息和变量实例的关系);在第三行,s1进行了改变,根据内部的逻辑规则,Delphi将自动分配新的内存并实际拷贝s1+'!'的内容到新的内存中,然后改变s1的地址和s2指向字串的引用计数就搞定了。这就是所谓的copy-on-write。你说了,这没什么用啊,哪儿这么多直接的赋值啊?其实像返回字串的函数这类情况都能发挥copy-on-write的好处,经济、快速。

综合一下,在Delphi编程中应该尽可能的使用string类型简化代码、减少出错并提高程序的运行效率。在调用C或者其他应用PChar的场合可以直接拿PChar(string)来用,不存在效率问题(因为只是强制转换而已)。字符数组主要用于定宽字串和定义结构时候用,不过只有下标为0且数组成员类型为char的array才和PChar兼容。
flyby 2000-09-20
  • 打赏
  • 举报
回复
补充:
设s、c、p分别为string、char、pchar类型,他们的值都为'hello';
1、s[1]值为'h',c[1]值为'e',p[1]值为'e';
2、p:=c,s:=c是正确的,p:=s错误的;
3、他们分别为字符串类型、数组类型、指针类型;
allexit 2000-09-20
  • 打赏
  • 举报
回复
string其实是一个类,他没有结束符,但有串长度.
char就是一个一个的字符了,
pchar就是c++中的string,以一个#0结尾.存在的原因如xiaohuilau所讲.
不知道我记得对不对,
xiaohuilau 2000-09-20
  • 打赏
  • 举报
回复
以我个人的观点睇,它们对于一般用户来讲速度的差别不大;而 PChar 是为了Delphi 与 Api 函数之间的事了。因为 Api 是用 C++ 写的,在 C++ 里不存在 String。所以 PChar 是为了能与兼容的。
gigi2000 2000-09-20
  • 打赏
  • 举报
回复
我回去仔细体会一下,然后就给分

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧