很不幸于现在才有时间看这本98年出版的书。刚看了第一章的第一节,就感触颇深。这几年对delphi的使用,可谓是只知皮毛!
感受之处不敢独享,特写出来与大家共享。错误之处还请大虾们指教!
很厚的一本书,以后还会继续增加,希望共同探讨、学习,谢谢!
1、存储
var
s : string;
beign
s := ‘Hi’;
引用计数
字符长度 add
Pchar终止符
(整数)
|
(整数)
|
H
|
i
|
#0
|
|
|
-8
-4 1 2 3 4 ……
字符串的地址往前偏移4个字节,保存的是字符串的长度(不是Pchar的长度),再往前偏移4个字节,是字符串的引用计数。
我们可以通过以下两个函数得到这两个值:
function GetRefCount(const s : string) : Integer;
var
RefCountPointer : Pointer;
begin
if Pointer(s) <> nil then
begin
RefCountPointer := Pointer(Integer(Pointer(s)) - 8);
Result := Integer(RefCountPointer^);
end
else
Result := 0;
end;
function GetSize(const s : string) : Integer;
var
SizePointer : Pointer;
begin
if Pointer(s) <> nil then
begin
SizePointer := Pointer(Integer(Pointer(s)) - 4);
Result := Integer(SizePointer^);
end
else
Result := 0;
end;
2、参数修饰
用const进行修饰(如上函数),因为将字符串作为一个非const参数传递,会复制字符串,并且会临时增加引用计数。
3、PChar
如下使用:
var
Test : string;
begin
SetLength(Test,100);
GetWindowText(Handle,PChar(Test),100);
则使用Length或GetSize,得到的字符串的长度仍然是100,而不是实际的长度(即这连个函数得到字符串长度时,没有读取PChar的终止符。因为Delphi无法知道GetWindowText改变了Test的内容,所以不能自动为字符串重新设置长度信息。
此时如果修改Test字符串(比如Test := Test + ‘%’;),那么字符串的长度依旧在100的基础上增加,但是显示却看不到新增加的字符。
此时解决上述问题有两种方法:
(1)Test := PChar(Test);
(2)SetLength(Test,StrLen(PChar(Test)));
其中第一种方法等同于Test := String(PChar(Test)),这种写法会把字符串复制到一个新的地址上;第二种方法则不会复制到新的地址。所以第二种方法速度上稍微快些。
如上处理后,再进行字符串的相关操作,就可以得到字符串实际的大小和显示出字符串实际的字符。