4

我正在尝试为大学的一门课程学习 Ada,但我在思考其中的一些想法时遇到了很多问题。

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

我这样声明矩阵和函数:

type MATRIX is array(INTEGER range <>, INTEGER range <>) of INTEGER;
function RemoveFirstRowCol (InMatrix: in MATRIX) return MATRIX is

然后我决定要返回的矩阵的大小:

     Result_matrix: MATRIX (InMatrix'First(1) .. InMatrix'Length(1) - 1, InMatrix'First(2) .. InMatrix'Length(2) - 1);

然后我进行计算并返回 Result_matrix。

所以这是我的问题:在运行它时,我发现如果我尝试将此函数的结果返回到不是以正确大小声明的 Matrix 的任何内容,我会在运行时遇到异常。

我的问题是,我这样做对吗?在我看来,我不应该提前知道函数会在大小方面返回什么。即使声明的矩阵大于我返回的矩阵,我仍然会收到错误消息。再说一次,Ada 的整个想法是强类型,所以也许这是有道理的(我应该确切地知道返回类型)。

无论如何,我这样做是否正确,如果事先不知道返回矩阵的大小,真的没有办法使用这个函数吗?

谢谢,伊丹

4

4 回答 4

4

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

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;

警告:由于结果矩阵是在堆栈上分配的,如果行数和列数很大,您可能会遇到问题。

于 2009-11-14T02:32:38.973 回答
1

因为您的 MATRIX 类型是使用未绑定索引声明的,所以该类型是不完整的。这意味着它可以由函数返回。在这种情况下,这就像指针一样。当然编译器不知道编译时的确切索引,结果矩阵将始终在堆中分配。

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

m:MATRIX(11..15,11..20);

在这种情况下,m'first(1) 是 11,m'length(1) 是 5!所以你得到:

Result_matrix:MATRIX(11..4,11..9);

这是 CONSTRAINT_ERROR...

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

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

于 2010-01-20T12:57:26.957 回答
0

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

于 2009-11-13T21:36:36.883 回答
0

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

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 ;
于 2009-11-13T21:42:50.293 回答