当参数类型是char的开放阵列时,是否允许使用动态char阵列?
-
04-10-2019 - |
题
我在看 Delphi:char和tchararray阵列“不兼容类型” 并开始实验。我发现的很有趣。
procedure Clear(AArray: array of Integer);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := 0;
end;
var
MyArray: array of Integer;
begin
Clear(MyArray);
end.
这个简单的小示例显示了如何使用开放阵列参数将动态数组传递到过程。它编译并完全按预期运行。
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
begin
Clear(MyArray);
end.
这几乎是相同的代码 Char
而不是 Integer
. 。它不编译。相反,编译器吐出了:
E2010 Incompatible types: 'Array' and 'Dynamic array'
为什么会这?
搜索一段时间后,我发现了 这 QC报告。我正在运行Delphi 2009,但仍在发生。
解决方案
由于该文档专门提及类型char的开放数组参数与动态数组兼容,因此这应该是一个错误。从 “打开数组参数”:
function Find(A: array of Char):
整数;
[...]
笔记: ...]上一个示例创建一个函数,该函数采用任何字符元素,包括(但不限于)动态数组。 [...
其他提示
您可以使用这种数组,定义自己的类型:
type
TCharDynArray = array of char;
procedure Clear(AArray: TCharDynArray);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
procedure test;
var
MyArray: TCharDynArray;
begin
Clear(MyArray);
end;
此代码将符合罚款。当然,它没有做任何有用的事情(Aarray参数未将其设置为“ VAR”,因此在为每个项目分配#0之前,将其复制在堆栈上)。但至少它是编译的。
在实践中,我发现更容易定义或使用高级类型进行动态数组(例如Tintegerdynarray),因为至少它允许您使用var作为参考,因此避免在堆栈上制作副本,使您的代码更快。
关于映射到PCHAR,这是所有动态阵列的通常:您可以将tintegerdynarray映射到指针上,然后将其用作pinteger或pintegerarray:
procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
n := Length(Values);
SetLength(Values,n+1);
Values[n] := Value;
end;
procedure Loop(V: PInteger);
begin
if V<>nil then
while V^<>0 do begin
write(V^,' ');
inc(V); // go to next integer in array
end;
end;
var IntArray: TIntegerDynArray;
begin
Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
AddInteger(IntArray,2);
AddInteger(IntArray,3);
AddInteger(IntArray,0);
Loop(pointer(IntArray)); // will display '2 3 '
end.
问题是与“整数数组”不一致的“ char”代码蜜蜂无疑是编译器的内在物质,并且PCHAR可以将PCHAR类型化为字符串。
我认为原因是 array of Char
与 PChar
, ,因为该代码确实编译:
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
P: PChar;
begin
Clear(P^);
end.
这可能是出于历史原因。
希望 巴里·凯利(Barry Kelly) 或者 丹尼·索普(Danny Thorpe) 将启动并为此提供更多反馈。
- 杰罗恩