[英]How to use 'Last attribute on multidimensional arrays in Ada?
我正在嘗試在 Ada 中將'Last
一個”屬性與二維數組一起使用,但我似乎無法找到正確的語法來執行此操作。
我知道,如果我有一個一維數組/向量,我可以使用 A'last 或 A'last(n),其中 n 是第 n 個維度。 但是,如果我執行以下操作
type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer;
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
for i in 0..tempTable'last(1) loop
for j in 0..tempTable'last(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
end temp;
我收到以下編譯時錯誤:
Storage_Error 堆棧溢出(或錯誤的 memory 訪問)
那我做錯了什么?
我在 Linux 上使用 GNAT Pro 6.4.1。
如果您在該代碼上遇到編譯時Storage_Error
,我會感到非常驚訝。
我已經獲取了您的代碼的副本並按如下方式對其進行了修改; 它使用 GNAT (gcc-4.4) 編譯沒有錯誤:
procedure Array_2D is
type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer;
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
for i in 0..tempTable'last(1) loop
for j in 0..tempTable'last(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
return 42; -- added this
end temp;
begin
null;
end Array_2D;
(請注意,我必須在temp
中添加缺少的return
語句。)
'Last
屬性(不是“命令”)的語法是正確的,但由於 Ada arrays 可以具有任意下限和上限,因此最好改用'Range
屬性:
for i in tempTable'Range(1) loop
for j in tempTable'Range(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
至於Storage_Error
異常,如果您使用非常大的tempIn
值調用temp
function,則很容易在運行時(而非編譯時)發生這種情況。 請記住,它必須分配足夠的空間來容納tempIn**2
Integer
對象。 大概您還創建了另一個UnconstrainedArray_2D
object 作為Table
參數傳入。
可以想象編譯器本身可能會因Storage_Error
異常而終止,但我在您的代碼中看不到任何可能導致這種情況的內容。
向我們展示一個完整的(但很小的)程序來演示您遇到的問題,以及准確的(復制和粘貼的)錯誤消息。 請清楚區分編譯時錯誤和運行時錯誤。
您的tempTable
的范圍可能為0..tempIn
,但您不知道您的Table
的范圍是什么。它們的長度也可能不同。
您必須檢查長度是否相同,然后使用相對索引,如下所示:
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
if tempTable'Length (1) /= Table'Length (1) or else
tempTable'Length (2) /= Table'Length (2)
then
raise Constraint_Error; -- or something else
end if;
for i in 0 .. tempTable'Length (1) - 1 loop
for j in 0 .. tempTable'Length (2) - 1 loop
tempTable(tempTable'First (1) + i, tempTable'First (2) + j) :=
Table(Table'First (1) + i, Table'First (2) + j);
end loop;
end loop;
end temp;
這樣可以確保兩個表的長度相同並且所有索引都有效。
如果允許您的tempTable
小於Table
,只需將長度檢查調整為>
。 索引仍然有效。
我沒有看到tempIn集的實際值。 如果進入 function temp 的tempIn的值沒有被正確初始化或顯式設置,那么tempIn中的值可以是任何東西,也可能不是你想要的東西。
我在想一個默認值。 (當我感覺不舒服時可能不應該發帖:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.