我正在努力学习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的任何内容,我会在运行时获得异常。
我的问题是,我这样做了吗?在我看来,我不应该提前知道函数将在大小方面返回什么。即使声明的Matrix 更大比我回来的还要强,我仍然会收到错误。再说一次,Ada的整个想法都是强类型,所以也许这是有意义的(我应该确切知道返回类型)。
无论如何,我是否正确地做了这个,并且在事先不知道返回矩阵的大小的情况下真的没有办法使用这个函数吗?
谢谢, 鹅蛋
答案 0 :(得分:3)
您不需要事先知道返回矩阵的大小,也不需要使用访问(指针)类型。只需在单元或块的声明部分调用您的函数,并自动设置边界:
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;
警告:由于结果矩阵是在堆栈上分配的,如果行数和列数很大,则可能会出现问题。
答案 1 :(得分:0)
调用者知道它传递给函数的矩阵的维数,因此调用者可以根据这些维度定义存储函数返回值的变量的类型。这真的不起作用吗?
答案 2 :(得分: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 ;
答案 3 :(得分:0)
因为您的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也是不完整的,这就是为什么它可以被函数返回。