有没有办法在数组中编写索引,如A(I)而不是A(A' First + I)?

时间:2015-09-01 15:23:30

标签: arrays ada

我必须编写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

,代码行的增长​​范围比我给出的示例宽得多

3 个答案:

答案 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相同的内存。