从Ada中的函数返回可变大小的矩阵

从Ada中的函数返回可变大小的矩阵,ada,Ada,我正试图在大学里学习Ada的一门课程,但我对其中的一些想法感到困惑 我目前的绊脚石:假设我有一个函数,它接受一个矩阵(只是一个二维整数数组),并返回一个新的更小的矩阵(去掉第一行和第一列) 我声明矩阵和函数如下: type MATRIX is array(INTEGER range <>, INTEGER range <>) of INTEGER; function RemoveFirstRowCol (InMatrix: in MATRIX) return MATRIX

我正试图在大学里学习Ada的一门课程,但我对其中的一些想法感到困惑

我目前的绊脚石:假设我有一个函数,它接受一个矩阵(只是一个二维整数数组),并返回一个新的更小的矩阵(去掉第一行和第一列)

我声明矩阵和函数如下:

type MATRIX is array(INTEGER range <>, INTEGER range <>) of INTEGER;
function RemoveFirstRowCol (InMatrix: in MATRIX) return MATRIX is
然后我进行计算并返回结果_矩阵

所以我的问题是:当运行这个函数时,我发现如果我试图将这个函数的结果返回到任何不是以正确大小声明的矩阵的东西中,我会在运行时得到一个异常

我的问题是,我做得对吗?在我看来,我不应该提前知道函数在大小方面会返回什么。即使声明的矩阵比我得到的矩阵大,我仍然会得到一个错误。再说一遍,Ada的整个思想是强类型,所以这可能是有意义的(我应该确切地知道返回类型)

不管怎样,我这样做是否正确,在不事先知道返回矩阵的大小的情况下,是否真的无法使用此函数

谢谢,
Edan

调用者知道传递给函数的矩阵的维度,因此调用者可以根据这些维度定义存储函数返回值的变量类型。这真的不起作用吗?

您的函数在编译时无法知道结果矩阵的大小 您需要返回指向新矩阵的指针:

type Matrix is array (Positive range <>, Positive range <>) of Integer; 
type Matrix_Ptr is access Matrix; 

       -- chop the 1'th row and column
       function Chopmatrix (
             Inputmatrix : in     Matrix ) 
         return Matrix_Ptr is 
          Returnmatrixptr : Matrix_Ptr;  

       begin

          -- create a new matrix with is one row and column smaller
          Returnmatrixptr  := new Matrix(2 .. Inputmatrix'Last, 2..  Inputmatrix'Last(2) );
          for Row in Inputmatrix'First+1 .. Inputmatrix'Last loop
             for Col in Inputmatrix'First+1 .. Inputmatrix'Last(2) loop
                Returnmatrixptr.All(Row,Col) :=   Inputmatrix(Row,Col);
             end loop;

          end loop;
          return Returnmatrixptr;
       end Chopmatrix ;
类型矩阵是整数的数组(正范围,正范围);
类型矩阵_Ptr是访问矩阵;
--切掉第一行和第一栏
函数矩阵(
输入矩阵:在矩阵中)
返回矩阵_Ptr为
Returnmatrixptr:Matrix_Ptr;
开始
--创建一个新矩阵,其中一行和一列较小
Returnmatrixptr:=新矩阵(2..Inputmatrix'Last,2..Inputmatrix'Last(2));
对于Inputmatrix'First+1..中的行。。输入矩阵的最后一个循环
对于输入矩阵中的列'First+1。。输入矩阵的最后(2)个循环
Returnmatrixptr.All(行,列):=输入矩阵(行,列);
端环;
端环;
返回矩阵xptr;
端切矩阵;

您不需要事先知道返回矩阵的大小,也不需要使用访问(指针)类型。只需在单元或块的声明性部分调用函数,边界将自动设置:

procedure Call_The_Matrix_Reduction_Function (Rows, Cols : Integer) is

   Source_Matrix : Matrix(1 .. Rows, 1 .. Cols);

begin
   -- Populate the source matrix

   -- ...

   declare
      Result : Matrix := RemoveFirstRowCol (Source_Matrix)
      -- Result matrix is automatically sized, can also be declared constant
      -- if appropriate.
   begin
      -- Process the result matrix

      -- ...

   end;
end Call_The_Matrix_Reduction_Function;

警告:由于结果矩阵是在堆栈上分配的,如果行数和列数太多,则可能会出现问题。

因为矩阵类型是用未绑定索引声明的,所以类型不完整。这意味着它可以由函数返回。在本例中,它的作用与指针相同。当然,编译器在编译时不知道确切的索引,结果矩阵总是在堆中分配

你的解决方案应该有效。唯一的问题是,当您创建结果矩阵时,只有当原始矩阵索引以0开头时,它才会工作

m:MATRIX(11..15,11..20);
在这种情况下,m’first(1)是11,m’length(1)是5!所以你得到:

Result_matrix:MATRIX(11..4,11..9);
这是一个错误

改为使用最后一个属性。即使您通常使用0索引


但请记住,您不需要使用指向矩阵的指针,因为矩阵也是不完整的,这就是为什么它可以用于由函数返回的原因。

它确实可以工作,我只是觉得这有点尴尬(因为我不希望调用我的函数的人必须进行这些类型的计算)。学究,GNAT(不知道其他编译器)不会在堆上分配结果;它会在“辅助堆栈”上分配,并在离开作用域时自动取消分配。您几乎肯定不需要在堆上分配新的矩阵。如果目标变量是通过调用(
M:matrix:=RemoveFirstRowCol)初始化的(输入矩阵);
)它将在(辅助)堆栈上分配。
Result_matrix:MATRIX(11..4,11..9);