• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi无类型参数传递动态数组和静态数组

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前几天发现的一个相关的问题,总结了下,备忘:

相关几个函数声明:
procedure FillChar(var X; Count: Integer; Value: Byte);
procedure  CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
function THandleStream.Write(const Buffer; Count: Longint): Longint;

测试代码:

procedure TForm1.btn1Click(Sender: TObject);
var
verifyMsg :
array[0..48] of Char; //定长数组
signedLen : Integer;
verfyFile : TFileStream;
str :
string;
len : Integer;
begin
len :
= 48;
str :
= 'hello world';

FillChar(verifyMsg[
0], len, 0);
// OK
// FillChar(verifyMsg, len, 0);

CopyMemory(@verifyMsg[
0], PChar(@str[1]), Length(str)); //要从str[1] 开始copy
// OK
// CopyMemory(@verifyMsg, Pointer(str), Length(str)); //str pointer pchar都可以
// OK
// CopyMemory(@verifyMsg, @str[1], Length(str)); //要从str[1] 开始copy

verfyFile :
= TFileStream.Create('c:\\test.data', fmCreate or fmShareDenyRead);

// 方法1 Ok
verfyFile.Write(verifyMsg[
0], Length(verifyMsg));
// 方法 2 OK
// verfyFile.Write(PChar(@verifyMsg[0])^, Length(verifyMsg));
// 方法 3 OK
// verfyFile.Write(verifyMsg, Length(verifyMsg));

// 测试写入字符串
// 方法1 OK
// verfyFile.write(PChar(str)^,length(str));
// 方法 2 wrong
// 写入内容是错误的 可能是str的内部结构导致
// verfyFile.write(str, length(str));
// 方法 3 OK
// verfyFile.write(str[1], length(str));
// 方法 4 OK
// verfyFile.write(Pointer(str)^,length(str));

freeAndNil(verfyFile);
end;

procedure TForm1.btn2Click(Sender: TObject);
var
verifyMsg :
array of Char; //动态数组
signedLen : Integer;
verfyFile : TFileStream;
str :
string;
len : Integer;
begin
len :
= 48;
str :
= 'hello world';
SetLength(verifyMsg, len);

// Error FillChar 参数不是指针,如下这行所以是错的.
// FillChar(verifyMsg, len, 0);
FillChar(verifyMsg[
0], len, 0);

// OK 接收参数是指针
CopyMemory(@verifyMsg[
0], @str[1], Length(str));
// 要从str[1] 开始copy
// CopyMemory(verifyMsg, PChar(@str[1]), Length(str));
verfyFile :
= TFileStream.Create('c:\\test2.data', fmCreate or fmShareDenyRead);

// 方法 1 OK 接收参数是无参类型
// verfyFile.Write(PChar(@verifyMsg[0])^, Length(verifyMsg));
// 方法 2 OK 接收参数是无参类型
verfyFile.Write(verifyMsg[
0], Length(verifyMsg));

freeAndNil(verfyFile);
end;

 


原因和结论:

1.定长数组A就是一个变量,A和A[0], @A=@A[0]
动态数组B就是一个指针,B是数组的首地址.B=@B[0]
2.普通参数按值传递,常量参数和变量参数都是按地址传递的 ,无类型参数只能是常量或变量参数,都是按地址传递
3.Best Practise:在用数组作参数的时,不管静态动态一率从0开始,要求传无类型参数的时候一率用arr[0]是个好习惯。写成 arr[Low(arr)] 最好.

参考:
Delphi - 数组 详解
http://www.cnblogs.com/huangjacky/archive/2009/12/21/1628833.html
诡异的动态数组问题
http://bbs.2ccc.com/topic.asp?topicid=358558
关于指针和过程/函数的无类型 var 参数的问题。
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1938519


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi函数发布时间:2022-07-18
下一篇:
Delphi中给活动控件画上矩形边框发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap