我有10个双变量我想用值0进行初始化。它们是非结构化的,不是设计中的数组的一部分。
procedure Initialize;
var
a1, a2, a3, a4, a5, b1, b2, b3, b4, b5: Double;
begin
a1 := 0;
a2 := 0;
a3 := 0;
a4 := 0;
a5 := 0;
b1 := 0;
b2 := 0;
b3 := 0;
b4 := 0;
b5 := 0;
end;
为了重构那段代码,我引入了一个辅助方法AssignValue。
procedure Initialize;
var
a1, a2, a3, a4, a5, b1, b2, b3, b4, b5: Double;
begin
AssignValue(0,a1);
AssignValue(0,a2);
...
end;
procedure AssignValue(value: Double; var target: Double);
begin
target:= value;
end;
如何编写一个更通用的AssignValue
过程,该过程采用任意数量的参数并使调用AssignValue(0,a1,a2,a3,a4,a5,b1,b2,b3,b4,b5)
成为可能?
加分问题:如何编写该程序,以便以double
作为第一个参数,以任意顺序考虑int
或value: Int
引用。
答案 0 :(得分:7)
你可以这样做:
procedure AssignValue(const Value: Double; const Addresses: array of PDouble);
var
i: Integer;
begin
for i := low(Addresses) to high(Addresses) do
Addresses[i]^ := Value;
end;
这样称呼:
AssignValue(0.0, [@a1, @a2, @a3, ...]);
这里我们传递一个包含变量地址的开放数组。
要支持多种类型,您可以使用如下声明的重载:
procedure AssignValue(const Value: Double; const Addresses: array of PDouble);
overload;
procedure AssignValue(const Value: Integer; const Addresses: array of PInteger);
overload;
// and so on, implementation of these functions is obvious
由您来判断这是否比您当前的解决方案更好。就个人而言,我坚持使用普通的旧任务操作员。另一种选择是将变量放在记录中并将Default(TMyRecord)
分配给记录变量。
答案 1 :(得分:2)
您可以使用开放数组参数:
procedure AssignValue(value: double; const arr: array of PDouble);
var
i: Integer;
begin
for i := 0 to length(arr)-1 do
PDouble(arr[i])^ := value;
end;
像这样使用它(我没有看到避免“@”用于此类任务的方法):
AssignValue(1, [@a1,@a2,@a3]);
答案 2 :(得分:0)
首先,您可以使用记录并致电fillchar(myrecord,sizeof(myrecord),0)
但如果您有一些内部参考计数值(例如string
),则可能容易出错。
但在你的情况下,因为它只有double
个值,所以写起来可能很容易:
procedure Initialize;
var localdata: record
a1, a2, a3, a4, a5, b1, b2, b3, b4, b5: Double;
obj: TObject;
i1, i2, i3, i4: integer;
end;
begin
fillchar(localdata,sizeof(localdata),0);
with localdata do
begin
a1 := 10;
a2 := a1+10;
assert(obj=nil);
inc(i1,20);
i2 := i1+10;
assert(i2=30);
end;
end;
如您所见,您甚至可以在记录中混合类型。诀窍在于您可以内联定义记录类型,而不需要任何类型定义。
我承认这不是直接的答案,但我谦虚地建议您更改您的设计以切换到更“兼容OOP”的内容。
只需使用动态数组或类来嵌入值。默认情况下,它们都将设置为0。
对于动态数组:
var a,b: array of double;
SetLength(a,5); // then use a[0] instead of a1, a[2] instead of a2...
SetLength(b,5); // then use b[0] instead of b1, b[2] instead of b2...
对于一个类 - 这是我的首选,因为您可以将代码嵌入数据中,作为好对象:
type
TMyClass = class
public
a1, a2, a3, a4, a5, b1, b2, b3, b4, b5: Double;
procedure OneMethodHere;
function OneTestHere(aValue: double): boolean;
end;
var C: TMyClass;
C := TMyClass.Create; // every C member will be set to 0
try
if C.OneTestHere(10) then
C.OneMethodHere;
// you can use C.a1 or C.b5
finally
C.Free;
end;