Arrays 如何实现未经检查的访问
我正在尝试设计一个自动扩展的2D阵列 矩形广告Arrays 如何实现未经检查的访问,arrays,ada,gnat,Arrays,Ada,Gnat,我正在尝试设计一个自动扩展的2D阵列 矩形广告 generic type Value_Type is private; package Rectangular is function Get ( Row, Col : Integer) return Value_Type; procedure Set ( Row, Col : Integer; Value : Value_Type); private type Matrix is array
generic
type Value_Type is private;
package Rectangular is
function Get ( Row, Col : Integer) return Value_Type;
procedure Set ( Row, Col : Integer; Value : Value_Type);
private
type Matrix is array (Integer range <>, Integer range <>) of aliased Value_Type;
Item : access Matrix;
end Rectangular;
generic
type Element is private;
Default : Element;
package Rectangular is
-- Provides an X..Y matrix of Element, which can be used just like a 2D Array.
-- The bounds of the array adjust themselves to accomodate requested indexes.
-- Rule-of-thumb: ~5 millseconds to re-allocate an array of 1'000'000 (1'000 x 1'000) entries. YMMV.
-- Usage:
-- package Rect is new Rectangular (Element => Float, Default => 0.0);
-- use Rect;
-- Map : Rect.Matrix;
-- ...
-- Map(-25, 97) := 42.0;
-- The bounds are now -25..0, 0..97, 2'548 elements, all 0.0 except -25,97 = 42.0
type Matrix is tagged limited private
with
Constant_Indexing => Get_Element,
Variable_Indexing => Get_Reference;
type Element_Access is access all Element;
function Get_Element (M : in out Matrix; E : in Element_Access) return Element;
function Get_Element (M : in out Matrix; Row, Col : in Integer) return Element;
type Reference (R : access Element) is limited null record
with Implicit_Dereference => R;
function Get_Reference (M : in out Matrix; E : in Element_Access) return Reference;
function Get_Reference (M : in out Matrix; Row, Col : in Integer) return Reference;
private
type Backing is array (Integer range <>, Integer range <>) of Element;
type Backing_Access is access Backing;
type Matrix is tagged limited record
Items : Backing_Access;
end record;
end Rectangular;
这是编译的,但带有
6:17 warning: "Program_Error" will be raised at run time
6:17 warning: accessibility check failure
6:17 warning: in instantiation at rectangular.adb:29
当然,当我尝试运行它时,我得到了程序错误:矩形。adb:59可访问性检查失败
我不明白为什么,因为在块的范围之外不能清楚地访问“Rect”
我应该使用未经检查的访问来避免这种行为吗?如果是的话,它会是什么样子?
如果不是,正确的成语是什么?
我应该如何释放矩形中的“项”?
几天来,我一直在努力让它正常工作,但都没有成功,如果您能提供代码示例帮助,我将不胜感激。在类型矩阵之后添加
使用您自己的约定命名访问类型
然后,用矩阵p全局替换访问矩阵
然后,在Adjust_界限中,您似乎需要替换
Rowmax := Integer'Min (Item'Last (1), Row);
借
对于Colmax也是如此。在类型矩阵之后添加
使用您自己的约定命名访问类型
然后,用矩阵p全局替换访问矩阵
然后,在Adjust_界限中,您似乎需要替换
Rowmax := Integer'Min (Item'Last (1), Row);
借
<> P>> CalMax。< P>您可以考虑使用以下包规范中所示的模式来制作可扩展矩阵:
with Ada.Containers.Vectors;
generic
type Index_Type is range <>;
with package inner_vector is new Ada.Containers.Vectors(<>);
package Vector_Of_Vectors is
package V_Matrix is new Ada.Containers.Vectors(Index_Type => Index_Type,
Element_Type => Inner_Vector.Vector,
"=" => Inner_Vector."=");
use Inner_Vector;
end Vector_Of_Vectors;
现在,您可以修改V_矩阵类型的每个向量元素的长度,以及向V_矩阵添加更多向量元素
下面是实例化向量包中的向量包的一个小示例:
with Ada.Containers.Vectors;
with Vector_Of_Vectors;
with Ada.Text_IO; use Ada.Text_IO;
use Ada.Containers;
procedure Main is
package Int_Vector is new Ada.Containers.Vectors(Index_Type => Natural,
Element_Type => Integer);
use Int_Vector;
package Int_Matrix is new Vector_Of_Vectors(Index_Type => Natural,
inner_vector => Int_Vector);
use Int_Matrix;
Temp_Vect : Int_Vector.Vector;
Temp_Mat : V_Matrix.Vector;
begin
Temp_Vect := Int_Vector.Empty_Vector;
for I in 1..5 loop
Temp_Vect.append(I);
end loop;
Temp_Mat.Append(Temp_Vect);
temp_Vect := Int_Vector.Empty_Vector;
for I in 15..25 loop
Temp_Vect.append(I);
end loop;
Temp_Mat.Append(Temp_Vect);
for V of Temp_Mat loop
for I of V loop
Put(I'Image);
end loop;
New_Line;
end loop;
end Main;
您可以考虑使用以下包规范中所示的模式来创建可扩展矩阵:
with Ada.Containers.Vectors;
generic
type Index_Type is range <>;
with package inner_vector is new Ada.Containers.Vectors(<>);
package Vector_Of_Vectors is
package V_Matrix is new Ada.Containers.Vectors(Index_Type => Index_Type,
Element_Type => Inner_Vector.Vector,
"=" => Inner_Vector."=");
use Inner_Vector;
end Vector_Of_Vectors;
现在,您可以修改V_矩阵类型的每个向量元素的长度,以及向V_矩阵添加更多向量元素
下面是实例化向量包中的向量包的一个小示例:
with Ada.Containers.Vectors;
with Vector_Of_Vectors;
with Ada.Text_IO; use Ada.Text_IO;
use Ada.Containers;
procedure Main is
package Int_Vector is new Ada.Containers.Vectors(Index_Type => Natural,
Element_Type => Integer);
use Int_Vector;
package Int_Matrix is new Vector_Of_Vectors(Index_Type => Natural,
inner_vector => Int_Vector);
use Int_Matrix;
Temp_Vect : Int_Vector.Vector;
Temp_Mat : V_Matrix.Vector;
begin
Temp_Vect := Int_Vector.Empty_Vector;
for I in 1..5 loop
Temp_Vect.append(I);
end loop;
Temp_Mat.Append(Temp_Vect);
temp_Vect := Int_Vector.Empty_Vector;
for I in 15..25 loop
Temp_Vect.append(I);
end loop;
Temp_Mat.Append(Temp_Vect);
for V of Temp_Mat loop
for I of V loop
Put(I'Image);
end loop;
New_Line;
end loop;
end Main;
下面是一个动态自调整二维阵列的可能解决方案。用法:
package Rect is new Rectangular (Element => Float, Default => 0.0);
use Rect;
Map : Rect.Matrix;
...
Map(-25, 97) := 42.0;
如果每增加一次大小,重新分配底层数组的成本将是不可接受的,因此包分配的资源略多于减少重新分配所需的资源
示例Main不断扩展数组,直到堆耗尽,并记录每次重新分配的时间。我对编译代码的速度感到惊喜,重新分配1_000 X 1_000数组1_000_000个元素只需5毫秒:
以下是在以下计算机上运行的输出:
存储错误与预期一样,我有32Gb内存
这是我在《美国残疾人法案》中的第一次尝试,欢迎评论
main.ads
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Assertions; use Ada.Assertions;
with Rectangular;
procedure Main is
subtype Element is Float;
Default_Value : Element := 42.0;
package Rect is new Rectangular (Element => Element, Default => Default_Value);
use Rect;
Map : Rect.Matrix;
begin
declare -- warmup, ensure values get set and defaults are applied
begin
Map (0, 0) := 2.3;
Map (10, 10) := Map (0, 0) + 1.0;
Assert (Map (0, 0) = 2.3);
Assert (Map (10, 10) = 3.3);
Assert (Map (5, 5) = Default_Value);
end;
declare -- Exercise hard to get reallocation timings
Bytes : Long_Long_Integer;
MBytes : Long_Long_Integer;
ILong : Long_Long_Integer;
Current, Should : Element;
begin
for I in 0 .. 100_000 loop
Map (I, I) := Element (I * 3);
if I mod 10_000 = 0 then -- occasionally
-- Check every value. On diagonal=3*, Off diagonal=Default_Value
for Row in 0 .. I loop
for Col in 0 .. I loop
Current := Map (Row, Col );
if Row = Col then
Should := Element (Row * 3);
else
Should := Default_Value;
end if;
Assert (Current = Should);
end loop;
end loop;
-- Show progress
ILong := Long_Long_Integer (I);
Bytes := Ilong * Ilong * Long_Long_Integer (Element'Size) / 8;
MBytes := Bytes / 2 ** 20;
Put_Line (I'Image & " X " & I'Image & " is " & MBytes'Image & "Mb");
end if;
end loop;
end;
end Main;
矩形广告
generic
type Value_Type is private;
package Rectangular is
function Get ( Row, Col : Integer) return Value_Type;
procedure Set ( Row, Col : Integer; Value : Value_Type);
private
type Matrix is array (Integer range <>, Integer range <>) of aliased Value_Type;
Item : access Matrix;
end Rectangular;
generic
type Element is private;
Default : Element;
package Rectangular is
-- Provides an X..Y matrix of Element, which can be used just like a 2D Array.
-- The bounds of the array adjust themselves to accomodate requested indexes.
-- Rule-of-thumb: ~5 millseconds to re-allocate an array of 1'000'000 (1'000 x 1'000) entries. YMMV.
-- Usage:
-- package Rect is new Rectangular (Element => Float, Default => 0.0);
-- use Rect;
-- Map : Rect.Matrix;
-- ...
-- Map(-25, 97) := 42.0;
-- The bounds are now -25..0, 0..97, 2'548 elements, all 0.0 except -25,97 = 42.0
type Matrix is tagged limited private
with
Constant_Indexing => Get_Element,
Variable_Indexing => Get_Reference;
type Element_Access is access all Element;
function Get_Element (M : in out Matrix; E : in Element_Access) return Element;
function Get_Element (M : in out Matrix; Row, Col : in Integer) return Element;
type Reference (R : access Element) is limited null record
with Implicit_Dereference => R;
function Get_Reference (M : in out Matrix; E : in Element_Access) return Reference;
function Get_Reference (M : in out Matrix; Row, Col : in Integer) return Reference;
private
type Backing is array (Integer range <>, Integer range <>) of Element;
type Backing_Access is access Backing;
type Matrix is tagged limited record
Items : Backing_Access;
end record;
end Rectangular;
A.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Unchecked_Deallocation;
with Ada.Numerics.Generic_Elementary_Functions;
package body Rectangular is
Demo : constant Boolean := True; -- Set to False once you've watched the demo
function Create (Row_First, Row_Last, Col_First, Col_Last : Integer) return Backing_Access is
-- Create a Backing array of Element'Access with (possibly negative) bounds
begin
return Answer : Backing_Access :=
new Backing (Row_First .. Row_Last, Col_First .. Col_Last)
do
for I in Row_First .. Row_Last loop
for J in Col_First .. Col_Last loop
Answer (I, J) := Default;
end loop;
end loop;
end return;
end Create;
function Multiplier (Bounds : Integer) return Float is
-- From the bounds of an array, calculate a suitable, gentle increase
-- Bounds | Log/(1+bounds,2) | 1/That | Increase
-- 1 1.0 1.000 1
-- 10 3.5 0.289 3
-- 100 6.7 0.150 15
-- 1,000 10.0 0.100 100
-- 5,000 12.3 0.081 407
-- 10,000 13.3 0.075 753
-- 25,000 14.6 0.068 1,711
-- 100,000 16.6 0.060 6,021
--
-- So, for a matrix bound (row or column) that is 25'000,
-- the matrix will be resized to 25'000+1'711=26'711
package Floats is new Ada.Numerics.Generic_Elementary_Functions (Float);
Factor, Result : Float;
begin
Factor := Floats.Log (Float (1 + Bounds), 2.0);
Result := 1.0 + 1.0 / Factor;
-- Put_Line (Bounds'Image & ' ' & Factor'Image & ' ' & Result'Image);
return Result;
end Multiplier;
procedure Free is new Ada.Unchecked_Deallocation (Backing, Backing_Access);
-- Release a Backing.
-- We know that this is safe, as they are private and only *we* can allocate them
procedure Adjust_Bounds (M : in out Matrix; Row, Col : in Integer) is
-- Check to see if Row-Col is within the current bounds.
-- If not, enlarge the Backing to accomodate said Row-Col
begin
if M.Items = null then -- auto-initialise
M.Items := Create (Row, Row, Col, Col);
end if;
if Row >= M.Items'First (1) and Row <= M.Items'Last (1) and
Col >= M.Items'First (2) and Col <= M.Items'Last (2) then
return; -- In bounds, all is well
end if;
declare
Enlarged : Backing_Access;
Row_First, Row_Last : Integer;
Col_First, Col_Last : Integer;
Row_Range, Col_Range : Integer;
Row_Multiplier, Col_Multiplier : Float;
Start_Time, End_Time : Time;
begin
if Demo then
Start_Time := Clock;
end if;
Row_First := M.Items'First (1);
Row_Last := M.Items'Last (1);
Row_Range := Row_Last - Row_First + 1;
Row_Multiplier := Multiplier (Row_Range);
Col_First := M.Items'First (2);
Col_Last := M.Items'Last (2);
Col_Range := Col_Last - Col_First + 1;
Col_Multiplier := Multiplier (Col_Range);
-- Integer'Min because the requested index may be further out than our conservative expansion multiplier
if Row < Row_First then
Row_First := Integer'Min (Row, Row_First - Integer (Float (Row_Range) * Row_Multiplier));
elsif Row > Row_Last then
Row_Last := Integer'Max (Row, Row_Last + Integer (Float (Row_Range) * Row_Multiplier));
end if;
if Col < Col_First then
Col_First := Integer'Min (Col, Col_First - Integer (Float (Col_Range) * Col_Multiplier));
elsif Col > Col_Last then
Col_Last := Integer'Max (Col, Col_Last + Integer (Float (Col_Range) * Col_Multiplier));
end if;
Enlarged := Create (Row_First, Row_Last, Col_First, Col_Last);
-- Copy old to new
for R in M.Items'Range (1) loop
for C in M.Items'Range (2) loop
Enlarged (R, C) := M.Items (R, C);
end loop;
end loop;
Free (M.Items);
M.Items := Enlarged;
-- just for demonstration
if Demo then
declare
Seconds : Duration;
Size : Long_Long_Integer := Long_Long_Integer (Row_Range) * Long_Long_Integer (Col_Range);
begin
End_Time := Clock;
Seconds := End_Time - Start_Time;
Row_Range := Row_Last - Row_First + 1;
Col_Range := Col_Last - Col_First + 1;
Put_Line ("Resized to " & Row_First'Image & ".." & Trim (Row_Last'Image, Left) & ',' &
Col_First'Image & ".." & Trim (Col_Last'Image, Left) &
" = " & Size'Image & " entries in " & Duration'Image (Seconds) & " s");
end;
end if;
end;
end Adjust_Bounds;
function Get_Reference (M : in out Matrix; E : in Element_Access) return Reference is
(Reference'(R => E));
function Get_Element (M : in out Matrix; E : in Element_Access) return Element is
(M (E));
function Get_Element (M : in out Matrix; Row, Col : in Integer) return Element is
Result : Element;
begin
Adjust_Bounds (M, Row, Col);
Result := M.Items (Row, Col);
return Result;
end Get_Element;
function Get_Reference (M : in out Matrix; Row, Col : in Integer) return Reference is
begin
Adjust_Bounds (M, Row, Col);
-- Unrestricted_Access is wicked, but we know what we're doing and it's the only way
return Answer : Reference :=
Reference'(R => M.Items ( Row, Col)'Unrestricted_Access);
end Get_Reference;
end Rectangular;
下面是一个动态自调整二维阵列的可能解决方案。用法:
package Rect is new Rectangular (Element => Float, Default => 0.0);
use Rect;
Map : Rect.Matrix;
...
Map(-25, 97) := 42.0;
如果每增加一次大小,重新分配底层数组的成本将是不可接受的,因此包分配的资源略多于减少重新分配所需的资源
示例Main不断扩展数组,直到堆耗尽,并记录每次重新分配的时间。我对编译代码的速度感到惊喜,重新分配1_000 X 1_000数组1_000_000个元素只需5毫秒:
以下是在以下计算机上运行的输出:
存储错误与预期一样,我有32Gb内存
这是我在《美国残疾人法案》中的第一次尝试,欢迎评论
main.ads
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Assertions; use Ada.Assertions;
with Rectangular;
procedure Main is
subtype Element is Float;
Default_Value : Element := 42.0;
package Rect is new Rectangular (Element => Element, Default => Default_Value);
use Rect;
Map : Rect.Matrix;
begin
declare -- warmup, ensure values get set and defaults are applied
begin
Map (0, 0) := 2.3;
Map (10, 10) := Map (0, 0) + 1.0;
Assert (Map (0, 0) = 2.3);
Assert (Map (10, 10) = 3.3);
Assert (Map (5, 5) = Default_Value);
end;
declare -- Exercise hard to get reallocation timings
Bytes : Long_Long_Integer;
MBytes : Long_Long_Integer;
ILong : Long_Long_Integer;
Current, Should : Element;
begin
for I in 0 .. 100_000 loop
Map (I, I) := Element (I * 3);
if I mod 10_000 = 0 then -- occasionally
-- Check every value. On diagonal=3*, Off diagonal=Default_Value
for Row in 0 .. I loop
for Col in 0 .. I loop
Current := Map (Row, Col );
if Row = Col then
Should := Element (Row * 3);
else
Should := Default_Value;
end if;
Assert (Current = Should);
end loop;
end loop;
-- Show progress
ILong := Long_Long_Integer (I);
Bytes := Ilong * Ilong * Long_Long_Integer (Element'Size) / 8;
MBytes := Bytes / 2 ** 20;
Put_Line (I'Image & " X " & I'Image & " is " & MBytes'Image & "Mb");
end if;
end loop;
end;
end Main;
矩形广告
generic
type Value_Type is private;
package Rectangular is
function Get ( Row, Col : Integer) return Value_Type;
procedure Set ( Row, Col : Integer; Value : Value_Type);
private
type Matrix is array (Integer range <>, Integer range <>) of aliased Value_Type;
Item : access Matrix;
end Rectangular;
generic
type Element is private;
Default : Element;
package Rectangular is
-- Provides an X..Y matrix of Element, which can be used just like a 2D Array.
-- The bounds of the array adjust themselves to accomodate requested indexes.
-- Rule-of-thumb: ~5 millseconds to re-allocate an array of 1'000'000 (1'000 x 1'000) entries. YMMV.
-- Usage:
-- package Rect is new Rectangular (Element => Float, Default => 0.0);
-- use Rect;
-- Map : Rect.Matrix;
-- ...
-- Map(-25, 97) := 42.0;
-- The bounds are now -25..0, 0..97, 2'548 elements, all 0.0 except -25,97 = 42.0
type Matrix is tagged limited private
with
Constant_Indexing => Get_Element,
Variable_Indexing => Get_Reference;
type Element_Access is access all Element;
function Get_Element (M : in out Matrix; E : in Element_Access) return Element;
function Get_Element (M : in out Matrix; Row, Col : in Integer) return Element;
type Reference (R : access Element) is limited null record
with Implicit_Dereference => R;
function Get_Reference (M : in out Matrix; E : in Element_Access) return Reference;
function Get_Reference (M : in out Matrix; Row, Col : in Integer) return Reference;
private
type Backing is array (Integer range <>, Integer range <>) of Element;
type Backing_Access is access Backing;
type Matrix is tagged limited record
Items : Backing_Access;
end record;
end Rectangular;
A.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar; use Ada.Calendar;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Unchecked_Deallocation;
with Ada.Numerics.Generic_Elementary_Functions;
package body Rectangular is
Demo : constant Boolean := True; -- Set to False once you've watched the demo
function Create (Row_First, Row_Last, Col_First, Col_Last : Integer) return Backing_Access is
-- Create a Backing array of Element'Access with (possibly negative) bounds
begin
return Answer : Backing_Access :=
new Backing (Row_First .. Row_Last, Col_First .. Col_Last)
do
for I in Row_First .. Row_Last loop
for J in Col_First .. Col_Last loop
Answer (I, J) := Default;
end loop;
end loop;
end return;
end Create;
function Multiplier (Bounds : Integer) return Float is
-- From the bounds of an array, calculate a suitable, gentle increase
-- Bounds | Log/(1+bounds,2) | 1/That | Increase
-- 1 1.0 1.000 1
-- 10 3.5 0.289 3
-- 100 6.7 0.150 15
-- 1,000 10.0 0.100 100
-- 5,000 12.3 0.081 407
-- 10,000 13.3 0.075 753
-- 25,000 14.6 0.068 1,711
-- 100,000 16.6 0.060 6,021
--
-- So, for a matrix bound (row or column) that is 25'000,
-- the matrix will be resized to 25'000+1'711=26'711
package Floats is new Ada.Numerics.Generic_Elementary_Functions (Float);
Factor, Result : Float;
begin
Factor := Floats.Log (Float (1 + Bounds), 2.0);
Result := 1.0 + 1.0 / Factor;
-- Put_Line (Bounds'Image & ' ' & Factor'Image & ' ' & Result'Image);
return Result;
end Multiplier;
procedure Free is new Ada.Unchecked_Deallocation (Backing, Backing_Access);
-- Release a Backing.
-- We know that this is safe, as they are private and only *we* can allocate them
procedure Adjust_Bounds (M : in out Matrix; Row, Col : in Integer) is
-- Check to see if Row-Col is within the current bounds.
-- If not, enlarge the Backing to accomodate said Row-Col
begin
if M.Items = null then -- auto-initialise
M.Items := Create (Row, Row, Col, Col);
end if;
if Row >= M.Items'First (1) and Row <= M.Items'Last (1) and
Col >= M.Items'First (2) and Col <= M.Items'Last (2) then
return; -- In bounds, all is well
end if;
declare
Enlarged : Backing_Access;
Row_First, Row_Last : Integer;
Col_First, Col_Last : Integer;
Row_Range, Col_Range : Integer;
Row_Multiplier, Col_Multiplier : Float;
Start_Time, End_Time : Time;
begin
if Demo then
Start_Time := Clock;
end if;
Row_First := M.Items'First (1);
Row_Last := M.Items'Last (1);
Row_Range := Row_Last - Row_First + 1;
Row_Multiplier := Multiplier (Row_Range);
Col_First := M.Items'First (2);
Col_Last := M.Items'Last (2);
Col_Range := Col_Last - Col_First + 1;
Col_Multiplier := Multiplier (Col_Range);
-- Integer'Min because the requested index may be further out than our conservative expansion multiplier
if Row < Row_First then
Row_First := Integer'Min (Row, Row_First - Integer (Float (Row_Range) * Row_Multiplier));
elsif Row > Row_Last then
Row_Last := Integer'Max (Row, Row_Last + Integer (Float (Row_Range) * Row_Multiplier));
end if;
if Col < Col_First then
Col_First := Integer'Min (Col, Col_First - Integer (Float (Col_Range) * Col_Multiplier));
elsif Col > Col_Last then
Col_Last := Integer'Max (Col, Col_Last + Integer (Float (Col_Range) * Col_Multiplier));
end if;
Enlarged := Create (Row_First, Row_Last, Col_First, Col_Last);
-- Copy old to new
for R in M.Items'Range (1) loop
for C in M.Items'Range (2) loop
Enlarged (R, C) := M.Items (R, C);
end loop;
end loop;
Free (M.Items);
M.Items := Enlarged;
-- just for demonstration
if Demo then
declare
Seconds : Duration;
Size : Long_Long_Integer := Long_Long_Integer (Row_Range) * Long_Long_Integer (Col_Range);
begin
End_Time := Clock;
Seconds := End_Time - Start_Time;
Row_Range := Row_Last - Row_First + 1;
Col_Range := Col_Last - Col_First + 1;
Put_Line ("Resized to " & Row_First'Image & ".." & Trim (Row_Last'Image, Left) & ',' &
Col_First'Image & ".." & Trim (Col_Last'Image, Left) &
" = " & Size'Image & " entries in " & Duration'Image (Seconds) & " s");
end;
end if;
end;
end Adjust_Bounds;
function Get_Reference (M : in out Matrix; E : in Element_Access) return Reference is
(Reference'(R => E));
function Get_Element (M : in out Matrix; E : in Element_Access) return Element is
(M (E));
function Get_Element (M : in out Matrix; Row, Col : in Integer) return Element is
Result : Element;
begin
Adjust_Bounds (M, Row, Col);
Result := M.Items (Row, Col);
return Result;
end Get_Element;
function Get_Reference (M : in out Matrix; Row, Col : in Integer) return Reference is
begin
Adjust_Bounds (M, Row, Col);
-- Unrestricted_Access is wicked, but we know what we're doing and it's the only way
return Answer : Reference :=
Reference'(R => M.Items ( Row, Col)'Unrestricted_Access);
end Get_Reference;
end Rectangular;
只要使用Ada.Containers。不要使用匿名访问类型。@BrianDrummond Ada.Containers据我所知没有二维数组。我的用例是一个矩阵行、列:1字节状态的整数,表示地面上的一个区域;当机器人发现新地形时,地图必须展开。向量向量看起来很笨拙,映射将使用大量的存储空间,并带有指向1字节标志的指针。来自.Net,我可能完全误解了Ada的理念,欢迎使用任何指针。@egilhh我的代码的哪部分具有匿名访问类型?“访问矩阵”是匿名的吗?@smirkingman,是的,您拥有访问矩阵的所有地方都是匿名的,因此不同于其他地方,具有不同的访问级别。必须使用Ada.Containers。不要使用匿名访问类型。@BrianDrummond Ada.Containers据我所知没有二维数组。我的用例是一个矩阵行、列:1字节状态的整数,表示地面上的一个区域;当机器人发现新地形时,地图必须展开。向量向量看起来很笨拙,映射将使用大量的存储空间,并带有指向1字节标志的指针。来自.Net,我可能完全误解了Ada的理念,欢迎使用任何指针。@egilhh我的代码的哪部分具有匿名访问类型?“访问矩阵”是匿名的吗?@smirkingman,是的,你拥有访问矩阵的所有地方都是匿名的,因此不同于其他地方,具有不同的访问级别谢谢,我不知道“访问矩阵”是匿名的
我们现在很好用。我可以问你我是如何“解放”旧矩阵的吗?谢谢谢谢你,我不知道“访问矩阵”是匿名的。现在很好用。我可以问你我是如何“解放”旧矩阵的吗?谢谢谢谢,但是我该如何实例化它呢?package Rect是一个新的向量,它的向量索引类型为>Integer,内部向量为>Integer?整数值示例:package Int Vect是一个新的Ada.Containers.VectorIndex类型为>Natural,元素类型为>Integer;包int_矩阵是_向量整数的新向量,int_向量;谢谢你的跟进。不幸的是,向量在我的用例中似乎不起作用:假设我有一个向量,它是空的。我追加0,0并将其设置为占用:=False,因为我站在那里。我想知道5,5号牢房是否有人住我打算沿着1,1..5,5号牢房走。我不能说cell5,5=是否被占用,因为没有一个向量的值是1..5,1..5,所以我必须在引用cell5,5之前附加空条目1..5,1..5。或者我完全误解了什么?如果你使用一个数组,你将创建数组并用一个值初始化它的元素,比如False或True。然后,您将根据应用程序的规则修改数组中的每个元素。你可以对向量做同样的事情。当然,访问向量元素的语法比数组的语法更详细。谢谢,但是我该如何实例化它呢?package Rect是一个新的向量,它的向量索引类型为>Integer,内部向量为>Integer?整数值示例:package Int Vect是一个新的Ada.Containers.VectorIndex类型为>Natural,元素类型为>Integer;包int_矩阵是_向量整数的新向量,int_向量;谢谢你的跟进。不幸的是,向量在我的用例中似乎不起作用:假设我有一个向量,它是空的。我追加0,0并将其设置为占用:=False,因为我站在那里。我想知道5,5号牢房是否有人住我打算沿着1,1..5,5号牢房走。我不能说cell5,5=是否被占用,因为没有一个向量的值是1..5,1..5,所以我必须在引用cell5,5之前附加空条目1..5,1..5。或者我完全误解了什么?如果你使用一个数组,你将创建数组并用一个值初始化它的元素,比如False或True。然后,您将根据应用程序的规则修改数组中的每个元素。你可以对向量做同样的事情。诚然,访问向量元素的语法比访问数组的语法更详细。