我正在尝试将相同的数组用于不同的操作,而不是使用3个不同的数组来节省空间。例如,在我的程序空间的某个部分中,未使用1..5,而另一部分空间3..8未被使用。
关键字重命名可以解决问题吗?这样的事情?
type SharedArray is array (integer range 1..10) of integer;
array1: SharedArray;
array2: SharedArray renames array1(1..5);
如果我是对的,那么array2不是一个全新的数组,只要它的值被改变就引用array1?
答案 0 :(得分:2)
我心中的第一个想法是“不,这不会起作用。”但后来我用GNAT GPL 2012写了这个:
with Text_IO; use Text_IO;
procedure Ren_Test is
type Shared_Array is array (Integer range 1 .. 10) of Integer;
Array1 : Shared_Array := (others => 42);
Array2 : Shared_Array renames Array1(1..5);
begin
Put_Line("Array1 range: " & Integer'Image(Array1'First) & " .."
& Integer'Image(Array1'Last));
Put_Line("Array2 range: " & Integer'Image(Array2'First) & " .."
& Integer'Image(Array2'Last));
New_Line;
Put_Line("Dump Array1");
for I in Array1'Range loop
Put(Integer'Image(Array1(I)));
if I /= Array1'Last then
Put(",");
end if;
end loop;
New_Line(2);
Put_Line("Dump and modify renaming Array2");
for I in Array2'Range loop
Put(Integer'Image(Array2(I)));
if I /= Array2'Last then
Put(",");
end if;
Array1(I) := Array1(I) + 17;
end loop;
New_Line(2);
Put_Line("Redump Array1");
for I in Array1'Range loop
Put(Integer'Image(Array1(I)));
if I /= Array1'Last then
Put(",");
end if;
end loop;
New_Line;
end Ren_Test;
运行它让我:
[35] Marc say: ./ren_test
Array1 range: 1 .. 10
Array2 range: 1 .. 5
Dump Array1
42, 42, 42, 42, 42, 42, 42, 42, 42, 42
Dump and modify renaming Array2
42, 42, 42, 42, 42
Redump Array1
59, 59, 59, 59, 59, 42, 42, 42, 42, 42
我会说我对此感到不舒服,主要是因为我希望将一个约束数组切割成小于声明大小的Constraint_Error。所以我知道这是合法代码,我知道GNAT GPL 2012编译并运行它没有问题。
当Shared_Array是一个无约束的数组时,我会更舒服:
type Shared_Array is array (Integer range <>) of Integer;
Array1 : Shared_Array (1..10) := (others => 42);
Array2 : Shared_Array renames Array1(1..5);
后者我希望符合标准。第一个,受约束的形式...恕我直言,如果。 (但我会留给语言律师来验证这一点。)
答案 1 :(得分:0)
如果要使用具有不同标识符的相同内存,则可以使用访问类型。但是,这对下标映射没有任何作用。
procedure Array_Alias is
type Shared_Array_Type is array (1 .. 10) of Integer;
Array_1 : aliased Shared_Array_Type := (others => 0);
Array_2 : access Shared_Array_Type := Array_1'Access;
begin
Array_1(1 .. 3) := (1, 2, 3);
Array_2(5 .. 8) := (others => -1);
for Index in 1 .. 10 loop
Text_IO.Put(Array_1(Index)'Img & " ");
end loop;
Text_IO.New_Line;
end Array_Alias;
产地:
1 2 3 0 -1 -1 -1 -1 0 0
编辑:Ada2005中添加了匿名访问类型。对于Ada95,需要声明数组类型的访问类型:
type Access_Shared_Array_Type is access all Shared_Array_Type;
Array_2 : Access_Shared_Array_Type := Array_1'Access;
答案 2 :(得分:0)
你明确要求的是别名。变量的别名往往会使我们的穷人感到困惑,并且可能导致一些非常微妙,难以发现的错误。它会使您的代码容易出错并且处理压力很大。简而言之,走样是邪恶的。
在这种情况下,由于精心设计的语言的魔力,它也是完全不同的。您所要做的就是将处理缓冲区的代码以不同的方式拆分到不同的例程中,并且就这些例程所知,它们处理的数组只有传递给它们的大小。例如,我写了这么短的代码:
with Ada.Text_Io;
procedure Ada_Slice is
type Integer_Array is array (Natural range <>) of Integer;
Integer_Buffer : Integer_Array (1..10) := (1,2,3,4,5,6,7,8,9,10);
procedure Magnify (Buffer : in out Integer_Array) is
begin
for I in Buffer'Range loop
Buffer(I) := Buffer(I) * 10;
end loop;
end Magnify;
procedure Swap (Front : in out Integer_Array;
Back : in out Integer_Array) is
Scratch : Integer;
begin
for I in Front'Range loop
Scratch := Front(I);
Front(I) := Back(Back'First + (I - Front'First));
Back(Back'First + (I - Front'First)) := Scratch;
end loop;
end Swap;
begin
Magnify(Integer_Buffer(6..10));
Swap (Integer_Buffer(1..2), Integer_Buffer(9..10));
for I in Integer_Buffer'range loop
Ada.Text_Io.Put (Integer'Image(Integer_Buffer(I)) & ",");
end loop;
Ada.Text_Io.New_Line;
end Ada_Slice;
运行时,输出当然是:
90,100,3,4,5,60,70,80,1,2,
(修复尾随逗号留给读者的练习)