Помимо того, что вы не знаете, как объявлять общую формальную подпрограмму (Райт показал, как это сделать для функций), в вашем коде есть ряд других проблем, которые, если их устранить, могут помочь вам отойти от того, кто думает о другомязык и переводит его на Ада в тот, кто на самом деле использует Ада.Предполагая, что вы хотите стать таким человеком, я укажу некоторые из них.
Вы объявляете свои типы массивов, используя Integer range <>
.В Аде более распространено использование Positive range <>
, потому что люди обычно ссылаются на позиции, начинающиеся с 1: 1, 2, 3, ...
Обобщения используются для повторного использования кода, а в реальной жизни такой кодчасто используется людьми, отличными от первоначального автора.Рекомендуется не делать необоснованных предположений о значениях, которые клиенты передадут вашим операциям.Вы предполагаете, что для Y> 0 for all I in 1 .. Y => I in X'range
и для Y <1 <code>1 in X'range.Хотя это верно для значений, которые вы используете, это вряд ли будет верно для всех применений процедуры.Например, когда массив используется как последовательность, как и здесь, индексы не имеют значения, поэтому более естественно записать ваш массив в виде (2, 10, 20, 30, 8)
.Если я это сделаю, Intarr'First = Integer'First и Intarr'Last = Integer'First + 4, оба из которых являются отрицательными.Попытка индексировать это с 1 вызовет Constraint_Error.
Y объявлен как Integer, что означает, что нулевые и отрицательные значения являются приемлемыми.Что значит передать -12 в Y?Здесь помогают подтипы Ады;если вы объявите Y как положительное, попытка передать ему не положительные значения завершится неудачей.
Z объявлен в режиме in out
, но на входное значение не ссылаются.Это было бы лучше, так как режим out
.
Y не нужен.Ада имеет реальные массивы;они носят свои границы с собой как X'First, X'Last и X'Length.Попытка индексировать массив за его пределами является ошибкой (уязвимости переполнения буфера невозможны).Обычный способ итерации по массиву - с помощью атрибута range:
for I in X'range loop
Это гарантирует, что I всегда является допустимым индексом для X.
Temp не инициализируется, поэтому он будетобычно инициализируется как "стек мусора".Вы должны ожидать получения разных результатов для разных вызовов с одними и теми же входами.
Вместо
if count > Y then
exit;
end if;
более обычно писать exit when Count > Y;
Поскольку ваша процедура производитодин скалярный вывод, для него было бы более естественным быть функцией:
generic -- Sum
type T is private;
Zero : T;
type T_List is array (Positive range <>) of T;
with function "+" (Left : T; Right : T) return T is <>;
function Sum (X : T_List) return T;
function Sum (X : T_List) return T is
Result : T := Zero;
begin -- Sum
Add_All : for I in X'range loop
Result := Result + X (I);
end loop Add_All;
return Result;
end Sum;
HTH