Arrays 打印整数数组在Ada中生成奇怪的输出
我创建了一个简单的Ada程序,允许用户用最多100个非负和非零整数填充一个数组,然后将它们打印出来。当我调用这个函数来打印数字时,它会打印出来,但同时它也会打印出一堆奇怪的、看似随机的数字。我在代码中犯了什么错误导致程序输出如此奇怪的结果?这是我第一次用Ada写作。例如,当我用数字[1,2,3,4,5]填充空数组时,会打印出以下内容:Arrays 打印整数数组在Ada中生成奇怪的输出,arrays,gcc,int,ada,Arrays,Gcc,Int,Ada,我创建了一个简单的Ada程序,允许用户用最多100个非负和非零整数填充一个数组,然后将它们打印出来。当我调用这个函数来打印数字时,它会打印出来,但同时它也会打印出一堆奇怪的、看似随机的数字。我在代码中犯了什么错误导致程序输出如此奇怪的结果?这是我第一次用Ada写作。例如,当我用数字[1,2,3,4,5]填充空数组时,会打印出以下内容: 1 2 3 4 5 32624 911328835
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;
在mkarr中,使用0或负值来标记输入的结束,但不将该值存储在数组中。如果在您输入的值结束后数组中存储的垃圾恰好是正数,则无法判断它不是有效值
在printarr中,如果遇到0或负值,则不会打印它,但会继续打印剩余的正值,这些正值是垃圾
如果将sentinel值存储在mkarr中,并在遇到sentinel时退出printarr中的打印,则程序应该可以工作
其他一些注意事项:
A和K仅在mkarr内部使用。它们应该是mkarr本地的
你从不使用Ada.Containers.Vectors。您可以删除相应的with和use指令
对于更高级的用法,您可以让mkarr返回一个仅包含输入数据的数组,方法是将Vector设置为无约束数组类型并返回一个切片。在mkarr中定义固定长度数组更容易。允许任意多个输入是一个骗局,但Ada.Containers可能是一个很好的方法。免责声明:我没有查看Ada.Containers。在mkarr中,您使用0或负值来标记输入的结束,但您不会将该值存储在数组中。如果在您输入的值结束后数组中存储的垃圾恰好是正数,则无法判断它不是有效值
在printarr中,如果遇到0或负值,则不会打印它,但会继续打印剩余的正值,这些正值是垃圾
如果将sentinel值存储在mkarr中,并在遇到sentinel时退出printarr中的打印,则程序应该可以工作
其他一些注意事项:
A和K仅在mkarr内部使用。它们应该是mkarr本地的
你从不使用Ada.Containers.Vectors。您可以删除相应的with和use指令
对于更高级的用法,您可以让mkarr返回一个仅包含输入数据的数组,方法是将Vector设置为无约束数组类型并返回一个切片。在mkarr中定义固定长度数组更容易。允许任意多个输入是一个骗局,但Ada.Containers可能是一个很好的方法。免责声明:我还没有看过Ada.Containers。扩展:
您需要一个可变长度的结果,因此更像Ada的方法是使用无约束数组:
类型向量是整数的数组正范围;
这意味着您可以创建任意大小的数组实例,只要边界为正:1。。100, 42 .. 43等。您甚至可以通过指定最后一个名为“last”的边界小于第一个名为“first”的边界来创建零长度数组。在这种特殊情况下,您可以使用“超出索引类型范围的最后一个”(在本例中为0,如果您想混淆人们,甚至可以使用-42!)
函数mkarr返回向量为
我们必须有一个实际数组来累加这些值,所以将上限设置为100
结果:载体1。。100;
我们需要知道有多少元素
Last : Natural := Result'First - 1;
多少和以前一样,
K:整数;
开始
Ada.Text_IO.Put
输入数字填充数组,负数或0将停止进程:;
对于结果范围循环中的I
我们可以返回最多包含结果长度元素的数组
Ada.Integer\u Text\u IO.Get K;
如果K>0,则
我们可以再添加一个元素
Last:=Last+1;
最后结果:=K;
其他的
元素少于100个,因此只返回该片段
return Result (Result'First .. Last);
end if;
end loop;
我们已经累积了100个结果,请返回所有结果
返回结果;
结束mkarr;
扩展到:
您需要一个可变长度的结果,因此更像Ada的方法是使用无约束数组:
类型向量是整数的数组正范围;
这意味着您可以创建任意大小的数组实例,只要边界为正:1。。100, 42 .. 43等。您甚至可以通过指定最后一个名为“last”的边界小于第一个名为“first”的边界来创建零长度数组。在这个特殊的环境下
nce,您可以使用“最后一个超出索引类型范围”在本例中为0,如果您想混淆人们,甚至可以使用-42
函数mkarr返回向量为
我们必须有一个实际数组来累加这些值,所以将上限设置为100
结果:载体1。。100;
我们需要知道有多少元素
Last : Natural := Result'First - 1;
多少和以前一样,
K:整数;
开始
Ada.Text_IO.Put
输入数字填充数组,负数或0将停止进程:;
对于结果范围循环中的I
我们可以返回最多包含结果长度元素的数组
Ada.Integer\u Text\u IO.Get K;
如果K>0,则
我们可以再添加一个元素
Last:=Last+1;
最后结果:=K;
其他的
元素少于100个,因此只返回该片段
return Result (Result'First .. Last);
end if;
end loop;
我们已经累积了100个结果,请返回所有结果
返回结果;
结束mkarr;
如前所述,您的示例没有进一步提到包。如果采用上述解决方案,您可能首先实例化通用包向量,以获得可调整大小的整数容器:
package Integer_Container is new Vectors (Natural, Integer);
然后,创建数组的函数可以声明名为a的向量,并将其元素和长度初始化为特定值:
function Make_Array (Size : Count_Type) return Vector is
A : Vector := To_Vector (New_Item => -1, Length => Size);
…
您可以在Ada 2012中使用,以简化Make_Array中的数据收集:
类似地,过程Print_Array a:in Vector可能会这样循环:
for E of A loop
Put (E, 4);
end loop;
Print_Array (Make_Array (42));
典型用法可能如下所示:
for E of A loop
Put (E, 4);
end loop;
Print_Array (Make_Array (42));
可以找到其他详细信息。如前所述,您的示例中提到了该软件包,没有进一步的参考。如果采用上述解决方案,您可能首先实例化通用包向量,以获得可调整大小的整数容器:
package Integer_Container is new Vectors (Natural, Integer);
然后,创建数组的函数可以声明名为a的向量,并将其元素和长度初始化为特定值:
function Make_Array (Size : Count_Type) return Vector is
A : Vector := To_Vector (New_Item => -1, Length => Size);
…
您可以在Ada 2012中使用,以简化Make_Array中的数据收集:
类似地,过程Print_Array a:in Vector可能会这样循环:
for E of A loop
Put (E, 4);
end loop;
Print_Array (Make_Array (42));
典型用法可能如下所示:
for E of A loop
Put (E, 4);
end loop;
Print_Array (Make_Array (42));
可以找到其他详细信息。快速修复:A:Vector:=其他=>0;然后做一些阅读来了解它是如何工作的以及为什么工作的。更好:使“mkarr”返回正确的大小向量,这很简单,不需要Ada.Containers.Quick fix:A:vector:=others=>0;然后做一些阅读来了解它是如何工作的以及为什么工作的。更好:使“mkarr”返回正确的大小向量,这很容易,并且不需要Ada.Containers。为了使事情更像Ada,可以让数组的组件为子类型正数,并将Count重命名为子类型Natural的最后一个,因为在一般情况下,它是使用的最后一个索引,这可能与增加的价值计数不同。@JeffreyR.Carter,好的观点;我采用了最后一个,但将数组的组件保留为整数,因为这是OP的选择。为了使事情更像Ada,我们将数组的组件设置为子类型正数,并将计数重命名为子类型Natural的最后一个,因为在一般情况下,它是使用的最后一个索引,这可能与增加的价值计数不同。@JeffreyR.Carter,好的观点;我采用了最后一个,但将数组的组件保留为整数,因为这是OP的选择