我想制作用Ada添加数组元素的子程序。 子程序" Add_Data"有3个参数 - 第一个参数=泛型类型数组(INTEGER数组或REAL数组) 第二个参数= INTEGER(数组大小) 第三个参数=泛型类型sum(INTEGER数组 - > sum将为INTEGER,REAL数组 - > sum将为REAL)
我是从ideone.com编程的。 (我想通过INTEGER数组查看结果。之后,我将通过REAL数组进行测试)
With Ada.Text_IO; Use Ada.Text_IO;
With Ada.Integer_Text_IO; Use Ada.Integer_Text_IO;
procedure test is
generic
type T is private;
type Tarr is array (INTEGER range <>) of T;
--function "+" (A,B : T) return T;
--function "+" (A, B : T) return T is
--begin
-- return (A+B);
--end "+";
procedure Add_Data(X : in Tarr; Y : in INTEGER; Z : in out T);
procedure Add_Data(X : in Tarr; Y : in INTEGER; Z : in out T) is
temp : T;
count : INTEGER;
begin
count := 1;
loop
temp :=temp+ X(count); //<-This is problem.
count := count + 1;
if count > Y then
exit;
end if;
end loop;
Z:=temp;
end Add_Data;
type intArray is array (INTEGER range <>) of INTEGER;
intArr : intArray := (1=>2, 2=>10, 3=>20, 4=>30, 5=>8);
sum : INTEGER;
procedure intAdd is new Add_Data(Tarr=>intArray, T=>INTEGER);
begin
sum := 0;
intAdd(intArr, 5, sum);
put (sum);
end test;
当我没有超载运算符&#34; +&#34;时,它会出错。 &#34;没有适用的运营商&#34; +&#34;私人类型&#34; T&#34;定义&#34。 我能为此做些什么?
答案 0 :(得分:7)
如果泛型的正式类型是private
,那么泛型中的任何内容都不能假设该类型的任何内容,除了它可以被赋值(:=
)并且它可以被比较为相等({{ 1}})和不平等(=
)。特别是,除非您提供,否则通用的其他运算符(例如/=
)都不可用。
这样做的方法是
+
这告诉编译器(a)有一个函数generic
type T is private;
with function "+" (L, R : T) return T is <>;
需要两个"+"
并返回一个T
; (b)如果实际的T
有一个与该个人资料匹配的运营商T
,则允许将其作为默认值。
所以,你可以说
"+"
或者,如果您不想使用默认值,
procedure intAdd is new Add_Data (T => Integer, ...
答案 1 :(得分:2)
除了不知道如何声明通用的正式子程序(Wright已经展示了如何为函数执行此操作)之外,您的代码还有许多其他问题,如果解决这些问题,可能会帮助您从另一个人那里思考语言并将其转换为Ada成为实际使用Ada的人。假设你想成为这样一个人,我会指出其中的一些。
使用Integer range <>
声明数组类型。在Ada中使用Positive range <>
更为常见,因为人们通常会提到从1开始的位置:第1,第2,第3 ......
泛型用于代码重用,在现实生活中,此类代码通常由原作者以外的人使用。优良做法是不对客户将传递给您的运营的价值做出未说明的假设。你假设,对于Y&gt; 0,for all I in 1 .. Y => I in X'range
和Y&lt; 1,1 in X'range
。虽然这对于您使用的值是正确的,但对于该过程的所有使用都不太可能。例如,当一个数组用作序列时,就像在这里一样,索引是无关紧要的,因此将数组aggreate写为(2, 10, 20, 30, 8)
更自然。如果我这样做,Intarr'First = Integer'First和Intarr'Last = Integer'First + 4,两者都是否定的。尝试将此索引为1将引发Constraint_Error。
Y被声明为整数,这意味着零和负值是可接受的。将-12传递给Y是什么意思? Ada的亚型有助于此;如果您将Y声明为正数,则尝试将非正值传递给它将失败。
Z被声明为模式in out
,但未引用输入值。这可以更好地作为模式out
。
不需要Y.阿达有真正的阵列;他们带着他们的边界作为X'First,X'Last和X'Length。尝试将数组索引到其边界之外是一个错误(没有缓冲区溢出漏洞可能)。迭代数组的常用方法是使用'range属性:
for I in X'range loop
这确保了我始终是X的有效索引。
Temp未初始化,因此通常会初始化为“stack junk”。对于使用相同输入的不同调用,您应该会得到不同的结果。
而不是
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