Ada - 一维数组操作
Ada - one dimensional array operations
参考 John Barnes 的书“Programming in Ada 2012”(ISBN:978-1-107-42481-4),第 138 页(第 8.6 节)。
procedure ArrayOps is
type Bit_Row is array (Positive range <>) of Boolean;
A, B : Bit_Row (1 .. 4);
T : constant Boolean := True;
F : constant Boolean := False;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A and B;
end ArrayOps;
我在作者提供的最小片段周围添加了一个简单的包装器,这似乎可以按预期进行编译和运行。
作者说这可以用 "Many of the operators" 来完成,这意味着 +
、*
、-
和 /
等算术。
我试图将其转换为使用整数数据类型的加法运算符,但遗憾的是这无法编译...
procedure ArrayOps is
type Int_Row is array (Positive range <>) of Integer;
A, B : Int_Row (1 .. 4);
T : constant Integer := 1;
F : constant Integer := 0;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A + B;
end ArrayOps;
编译器错误状态:arrayops.adb:12:10: there is no applicable operator "+" for type "Int_Row" defined at line 2
。这是唯一的错误。显然我的代码中缺少某些东西,但是这本书再也没有提到这个主题。如何为布尔运算符以外的运算符启用数组运算?
编辑:
我已经根据@egilhh 的回答修改了代码,因为这似乎是解决基本问题的最小更改集。
procedure ArrayOps is
type Int_Row is array (1 .. 4) of Integer;
function "+"(Left, Right : Int_Row) return Int_Row
is
Result : Int_Row;
begin
for I in Int_Row'Range loop --'
Result(I) := Left(I) + Right(I);
end loop;
return Result;
end "+";
A, B : Int_Row;
T : constant Integer := 1;
F : constant Integer := 0;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A + B;
end ArrayOps;
现在可以了。但是,我接受了 DeeDee 的回答,因为这可能是最佳实践解决方案。向两位致敬:)
"Many" 并不意味着 "all"... 具体来说,他提到 and
、or
、xor
和 not
一个-维度 Boolean
数组。当然,这些只是预定义的;没有什么能阻止您定义自己的运算符。看看第 169 页(第 10.2 节)。
function "+"(Left, Right : Int_Row) return Int_Row
is
Result : Int_Row;
begin
for I in Int_Row'Range loop --'
Result(I) := Left(I) + Right(I);
end loop;
return Result;
end "+";
与"many operators"书中提到的逻辑和关系运算符。只有这些运算符是按照语言标准的要求为一维数组类型隐式定义的(请参阅 RM 4.5.1 (2) and RM 4.5.2 (1))。
对于其他运算符,您需要自己实现它们:
arrayops.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO;
procedure ArrayOps is
type Int_Row is array (Positive range <>) of Integer;
A, B : Int_Row (1 .. 4);
T : constant Integer := 1;
F : constant Integer := 0;
---------
-- "+" --
---------
function "+" (A, B : Int_Row) return Int_Row is
begin
if A'Length /= B'Length then
raise Constraint_Error with "array lengths do not match";
end if;
declare
Result : Int_Row (1 .. A'Length);
begin
for I in Result'Range loop
Result (I) := A (A'First + I - 1) + B (B'First + I - 1);
end loop;
return Result;
end;
end "+";
---------
-- Put --
---------
procedure Put (A : Int_Row; Width : Natural := 0) is
use Ada.Integer_Text_IO;
begin
for I in A'Range loop
Put (A (I), Width);
end loop;
end Put;
begin
A := (T, T, F, F);
B := (T, F, T, F);
Put (A, 2); New_Line;
Put (B, 2); New_Line;
A := A + B;
Put ("--------- +"); New_Line;
Put (A, 2); New_Line;
end ArrayOps;
输出
1 1 0 0
1 0 1 0
--------- +
2 1 1 0
参考 John Barnes 的书“Programming in Ada 2012”(ISBN:978-1-107-42481-4),第 138 页(第 8.6 节)。
procedure ArrayOps is
type Bit_Row is array (Positive range <>) of Boolean;
A, B : Bit_Row (1 .. 4);
T : constant Boolean := True;
F : constant Boolean := False;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A and B;
end ArrayOps;
我在作者提供的最小片段周围添加了一个简单的包装器,这似乎可以按预期进行编译和运行。
作者说这可以用 "Many of the operators" 来完成,这意味着 +
、*
、-
和 /
等算术。
我试图将其转换为使用整数数据类型的加法运算符,但遗憾的是这无法编译...
procedure ArrayOps is
type Int_Row is array (Positive range <>) of Integer;
A, B : Int_Row (1 .. 4);
T : constant Integer := 1;
F : constant Integer := 0;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A + B;
end ArrayOps;
编译器错误状态:arrayops.adb:12:10: there is no applicable operator "+" for type "Int_Row" defined at line 2
。这是唯一的错误。显然我的代码中缺少某些东西,但是这本书再也没有提到这个主题。如何为布尔运算符以外的运算符启用数组运算?
编辑:
我已经根据@egilhh 的回答修改了代码,因为这似乎是解决基本问题的最小更改集。
procedure ArrayOps is
type Int_Row is array (1 .. 4) of Integer;
function "+"(Left, Right : Int_Row) return Int_Row
is
Result : Int_Row;
begin
for I in Int_Row'Range loop --'
Result(I) := Left(I) + Right(I);
end loop;
return Result;
end "+";
A, B : Int_Row;
T : constant Integer := 1;
F : constant Integer := 0;
begin
A := (T, T, F, F);
B := (T, F, T, F);
A := A + B;
end ArrayOps;
现在可以了。但是,我接受了 DeeDee 的回答,因为这可能是最佳实践解决方案。向两位致敬:)
"Many" 并不意味着 "all"... 具体来说,他提到 and
、or
、xor
和 not
一个-维度 Boolean
数组。当然,这些只是预定义的;没有什么能阻止您定义自己的运算符。看看第 169 页(第 10.2 节)。
function "+"(Left, Right : Int_Row) return Int_Row
is
Result : Int_Row;
begin
for I in Int_Row'Range loop --'
Result(I) := Left(I) + Right(I);
end loop;
return Result;
end "+";
与"many operators"书中提到的逻辑和关系运算符。只有这些运算符是按照语言标准的要求为一维数组类型隐式定义的(请参阅 RM 4.5.1 (2) and RM 4.5.2 (1))。
对于其他运算符,您需要自己实现它们:
arrayops.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO;
procedure ArrayOps is
type Int_Row is array (Positive range <>) of Integer;
A, B : Int_Row (1 .. 4);
T : constant Integer := 1;
F : constant Integer := 0;
---------
-- "+" --
---------
function "+" (A, B : Int_Row) return Int_Row is
begin
if A'Length /= B'Length then
raise Constraint_Error with "array lengths do not match";
end if;
declare
Result : Int_Row (1 .. A'Length);
begin
for I in Result'Range loop
Result (I) := A (A'First + I - 1) + B (B'First + I - 1);
end loop;
return Result;
end;
end "+";
---------
-- Put --
---------
procedure Put (A : Int_Row; Width : Natural := 0) is
use Ada.Integer_Text_IO;
begin
for I in A'Range loop
Put (A (I), Width);
end loop;
end Put;
begin
A := (T, T, F, F);
B := (T, F, T, F);
Put (A, 2); New_Line;
Put (B, 2); New_Line;
A := A + B;
Put ("--------- +"); New_Line;
Put (A, 2); New_Line;
end ArrayOps;
输出
1 1 0 0
1 0 1 0
--------- +
2 1 1 0