打印整数数组会在Ada中生成奇怪的输出

时间:2020-05-03 01:42:36

标签: arrays gcc int ada

我创建了一个简单的Ada程序,该程序允许用户使用最多100个非负和非零整数填充数组,然后将其打印出来。当我调用该函数以打印数字时,它会打印出它们,但同时它还会打印出一堆奇怪的,看似随机的数字。我在代码中犯了什么错误,导致程序输出了如此奇怪的结果?这是我第一次在Ada写作。例如,当我用数字[1,2,3,4,5]填充空数组时,将输出以下内容:

    1
          2
          3
          4
          5
      32624
  911328835
      32624
  911328836
      32624
   67043328
  134217726
  134217726
 2013265921
  134217726
  134217726
  134217726
   67043328
  909181968
      32624
 2114692683
      89452
  914381552
      32624
 1543503876
          2
         14
          2
         14

我在ubuntu上使用gnatmake编译器,并且在编译源代码时不会给我任何错误/警告消息。

这是我的源代码,我知道我可能不需要使用单独的函数,但是我还是出于学习目的而实现了它们。

with Ada.Containers.Vectors;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
use Ada.Containers;


procedure thing is 
type Vector is array (1..100) of Integer;
A: Vector;--array doesn't need to be completely filled up

K: Integer;
--array filling function below
function mkarr return Vector is --asks user to fill empty array with positive and non zero integers

begin

Ada.Text_IO.Put ("enter numbers to fill array, negative or 0 will stop process: ");
for I in 1..100 loop
    Ada.Integer_Text_IO.Get(K);
    if K>0 then
        A(I) := K;
    end if;
    if K<=0 then
        return A;
    end if;

end loop;
return A;
end;




--array printing prodcedure below
procedure printarr(A: in out Vector) is
begin
    for I in A'Range loop
    if A(I)>0 then
        Ada.Integer_Text_IO.Put(A(I));
        New_Line(1);
    end if;
    end loop;
end printarr;



B: Vector := mkarr;


--main method below
begin



printarr(A);
end thing;

3 个答案:

答案 0 :(得分:6)

mkarr中,您使用0或负值来标记输入的结尾,但是您不将该值存储在数组中。如果在您输入的值的结尾之后数组中存储了任何垃圾,而这些垃圾恰好是正数,则无法断定它不是有效值。

printarr中,如果遇到0或负值,则不打印它-但您将继续打印其余的正值(这是垃圾)。

如果您将哨兵值存储在mkarr中,并且在遇到哨兵时退出在printarr中的打印,则程序应该可以工作。

其他一些注意事项:

AK仅在mkarr内部使用。它们应位于mkarr的本地。

您从不使用Ada.Containers.Vectors。您可以删除相应的withuse指令。

对于更高级的用法,可以通过使mkarr成为不受约束的数组类型并返回一个切片,来使Vector返回仅包含输入数据的数组。在mkarr内定义固定长度的数组仍然更加容易。允许任意输入很多是很麻烦的,但是Ada.Containers可能是一个很好的方法。 (免责声明:我没有看过Ada.Containers。)

答案 1 :(得分:3)

Keith’s answer上展开: 您需要一个可变长度的结果,因此更像Ada的方法是使用“无约束数组”:

type Vector is array (Positive range <>) of Integer;

这意味着您可以创建任意大小的数组实例,只要边界是正数即可:1 .. 100,42 .. 43等。您甚至可以通过指定最后一个边界(称为’Last)小于第一个边界(称为’First)。在这种特殊情况下,您可以在索引类型范围之外使用’Last(在这种情况下,如果要使人们感到困惑,则可以使用0或-42!)。

function mkarr return Vector is

我们必须有一个实际的数组来累加值,所以将上限设置为100。

   Result : Vector (1 .. 100);

我们需要知道有多少个元素。

   Last : Natural := Result'First - 1;

或多或少,

   K : Integer;
begin
   Ada.Text_IO.Put
     ("enter numbers to fill array, negative or 0 will stop process: ");
   for I in Result'Range loop

我们可以返回一个最多包含Result’Length个元素的数组。

      Ada.Integer_Text_IO.Get (K);
      if K > 0 then

我们可以再添加一个元素。

         Last := Last + 1;
         Result (Last) := K;
      else

少于100个元素,因此仅返回该切片。

         return Result (Result'First .. Last);
      end if;
   end loop;

我们已经累积了100条结果,因此请全部退回。

   return Result;
end mkarr;

答案 2 :(得分:1)

here所述,您的示例提到了Ada.Containers.Vectors,而没有进一步引用该软件包。如果您采用here所述的解决方案,则可以首先实例化通用包Vectors,以获得可调整大小的整数容器:

package Integer_Container is new Vectors (Natural, Integer);

然后,您创建数组的函数可以声明一个名为Vector的{​​{1}}并将其元素和长度初始化为特定值:

A

您可以在Ada 2012中使用Iteration来简化function Make_Array (Size : Count_Type) return Vector is A : Vector := To_Vector (New_Item => -1, Length => Size); … 中的数据收集:

Make_Array

类似地,for E of A loop Get (K); if K > 0 then E := K; else exit; end if; end loop; 可能会像这样循环:

procedure Print_Array (A : in Vector)

典型用法如下:

for E of A loop
   Put (E, 4);
end loop;

可以在herehere中找到其他详细信息。