我必须编写A(A'First + I)
以独立于索引定义。当它们很多时,它可能有点难以阅读。一个简单的例子:
procedure Dot_Accumulate (A : Number_Array; B : Number_Array; N : Natural; R : in out Number) is
begin
for I in 0 .. N - 1 loop
R := R + A(A'First + I) * B(B'First + I);
end loop;
end;
我希望代码看起来像这样:
procedure Dot_Accumulate (A : Number_Array; B : Number_Array; N : Natural; R : in out Number) is
begin
for I in 0 .. N - 1 loop
R := R + A(I) * B(I);
end loop;
end;
由于重复A'First + I
答案 0 :(得分:3)
如果Number_Array
是受约束的数组类型,只需执行:
for I in Number_Array'Range loop
R := R + A(I) * B(I);
end loop;
编辑:
如果您不介意额外复制,可以对无约束数组执行此操作(注意如何通过获取最短数组的长度来消除N
):
procedure Dot_Accumulate (A : Number_Array; B : Number_Array; R : in out Number) is
subtype N_A is Number_Array(1..My_Index_Type'Min(A'Length, B'Length));
Ax : N_A := N_A(A(A'First..A'First+N_A'Length-1));
Bx : N_A := N_A(B(B'First..B'First+N_A'Length-1));
begin
for I in N_A'Range loop
R := R + Ax(I) * Bx(I);
end loop;
end Dot_Accumulate;
答案 1 :(得分:0)
一个简单的选择是修复Number_Array'First
:
type Number_Array is array (Positive range <>) of Number
with Dynamic_Predicate => Number_Array'First = 1;
然后你可以编写你的循环:
for I in 1 .. N loop
R := R + A (I) * B (I);
end loop;
但除此之外,你的榜样令人难以置信的难看。你究竟想做什么?
答案 2 :(得分:0)
这是另一种选择:
procedure Dot_Accumulate (A : Number_Array; B : Number_Array; R : in out Number) with
Pre => A'Length = B'Length;
procedure Dot_Accumulate (A : Number_Array; B : Number_Array; R : in out Number) is
subtype Common_Range is Number_Array (1 .. A'Length);
Ax : Common_Range with Address => A'Address;
Bx : Common_Range with Address => B'Address;
begin
for I in Common_Range'Range loop
R := R + Ax(I) * Bx(I);
end loop;
end;
确保A和B具有相同的长度,因此不需要传递N参数。而且我不认为这会降低性能,因为Ax使用与A相同的内存。