请教TFileStream.write和Delphi中的数组指针相关问题

时间:2023-01-10 04:50:42

procedure TForm1.btn1Click(Sender: TObject);
var
  verifyMsg         : array[0..48] of Char;
  signedLen         : Integer;
  verfyFile         : TFileStream;
  str               : string;
begin
  str := 'hello world';
  FillChar(verifyMsg, SizeOf(verifyMsg), 0);
  CopyMemory(PChar(@verifyMsg[0]), PChar(@str[1]), Length(str));   //要从str[1] 开始copy
  verfyFile := TFileStream.Create('c:\\test.data', fmCreate or fmShareDenyRead);
  //方法 1
  //verfyFile.Write(pchar(@verifyMsg[0])^, Length(verifyMsg));    //OK 工作正常
  //方法 2
  //  verfyFile.Write(verifyMsg, Length(verifyMsg));                  //OK 工作正常

  //方法 3
 // verfyFile.write(pchar(str)^,length(str));      //OK 工作正常
 //方法 4
 //wrong  是不是因为string 内部结构不一样,如从索引1开始存储的是内容,方法3中的 pchar(str) 其实内部已经转换了.
 // verfyFile.write(str, length(str));

 //方法 5 OK  从索引1开始.
  verfyFile.write(str[1], length(str));
  freeAndNil(verfyFile);

end;

Q1:
function THandleStream.Write(const Buffer; Count: Longint): Longint;
这个函数的签名.buffer 类型是什么,好像是没有定义?它的意思是不是不是指针类型也行,具体根据buffer参数而定.

Q2:
方法一的代码是从网上看的,感觉完全是脱裤放屁,pchar(@verifyMsg[0])^ 先取数组指针,再转PChar再反解引用,于是我改成方法二了,工作正常,我的理解对么?在其他地方应用时,delphi中的数组名是不是也可以当成数组指针使用?

Q3:
方法4是有问题的, 是不是因为string 内部结构不一样,如从索引1开始存储的是内容,方法3中的 pchar(str) 其实内部已经转换了,把string转换成了char数组的指针了.所以方法3.4 的问题和1.2 不一样了.

请大家多多指教.

5 个解决方案

#1


为了避免因为字符串指针和指针之间弄成混淆,我把PChar->Pointer改成这样也可以

//方法 6
   verfyFile.write(Pointer(str)^,length(str));      //OK


我彻底晕了.

#2


#3


还有个问题:
如果 verfyMsg是动态数组,为啥要用下面这样才可以?
FillChar(verifyMsg[0], len, 0);
对比静态数组:
FillChar(verifyMsg, len, 0);

在网上搜了.
在动态数组中,数组名是数组首地址,在静态数组中则不然,可以认为是数组的第一个元素,取他的地址,@静态数组名 才是数组的首地址。

这还是很迷惑

#4


http://www.cnblogs.com/solo/archive/2010/12/01/1892708.html

疑惑我已自己解决,总结了下放在以上BLOG中.谢谢大家的回复

#5


String是Delphi独有的。
String[0]分两部分:长度、引用数 String[1]以后才是存储的内容
PChar类似C中的指针
动态数组系统默认的下标是从0开始的
FillChar(verifyMsg[0], len, 0);初始化数组,不显式的方式初始化,有可能出现莫名其妙的值的情况

#1


为了避免因为字符串指针和指针之间弄成混淆,我把PChar->Pointer改成这样也可以

//方法 6
   verfyFile.write(Pointer(str)^,length(str));      //OK


我彻底晕了.

#2


#3


还有个问题:
如果 verfyMsg是动态数组,为啥要用下面这样才可以?
FillChar(verifyMsg[0], len, 0);
对比静态数组:
FillChar(verifyMsg, len, 0);

在网上搜了.
在动态数组中,数组名是数组首地址,在静态数组中则不然,可以认为是数组的第一个元素,取他的地址,@静态数组名 才是数组的首地址。

这还是很迷惑

#4


http://www.cnblogs.com/solo/archive/2010/12/01/1892708.html

疑惑我已自己解决,总结了下放在以上BLOG中.谢谢大家的回复

#5


String是Delphi独有的。
String[0]分两部分:长度、引用数 String[1]以后才是存储的内容
PChar类似C中的指针
动态数组系统默认的下标是从0开始的
FillChar(verifyMsg[0], len, 0);初始化数组,不显式的方式初始化,有可能出现莫名其妙的值的情况