Ada protected Put 过程不写在同一行
Ada protected Put procedure doesn't write in the same line
我的问题是我创建了一个受保护的Safe_Printer
;但是当我使用它的过程时,它弄乱了 Put
函数。每次它打印到一个新行。我如何才能避免这种情况?基本上,我想以可读的格式打印我的矩阵。
这是我的代码:
with Ada.Text_IO;
use Ada.Text_IO;
procedure main is
type Matrix is array(integer range <>, integer range <>) of integer;
protected Safe_Printer is
procedure Put(S: String);
procedure Put(M: Matrix);
end Safe_Printer;
protected body Safe_Printer is
procedure Put(S: String) is
begin
for I in S'range loop
Put(S(I));
end loop;
New_Line;
end Put;
procedure Put(M:Matrix) is
begin
for I in m'range(1) loop
for j in m'range(2) loop
put(integer'image(m(i,j)) & " ");
end loop;
new_line(1);
end loop;
end Put;
end Safe_Printer;
m:Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put(m);
for I in m'range(1) loop
for j in m'range(2) loop
put(integer'image(m(i,j)) & " ");
end loop;
new_line(1);
end loop;
end main;
我的输出是:
1
2
3
4
5
6
1 2 3
4 5 6
因为 'Image
属性 returns a String
,您的 Put(M : Matrix)
实现在其内部循环中调用 Safe_Printer.Put(S : String)
;每个矩阵条目然后得到一个 New_Line
。一种解决方案是在 Safe_Printer.Put(M : Matrix)
:
中显式调用 Put
定义的语言
procedure Put(M : Matrix) is
begin
for I in M'range(1) loop
for j in M'range(2) loop
Ada.Text_IO.Put(integer'image(M(i,j)) & " ");
end loop;
New_Line;
end loop;
end Put;
经测试:
with Ada.Text_IO;
use Ada.Text_IO;
procedure main is
type Matrix is array(integer range <>, integer range <>) of integer;
protected Safe_Printer is
procedure Put(S : String);
procedure Put(M: Matrix);
end Safe_Printer;
protected body Safe_Printer is
procedure Put(S : String) is
begin
for I in S'range loop
Put(S(I));
end loop;
New_Line;
end Put;
procedure Put(M : Matrix) is
begin
for I in M'range(1) loop
for j in M'range(2) loop
Ada.Text_IO.Put(integer'image(M(i,j)) & " ");
end loop;
New_Line;
end loop;
end Put;
end Safe_Printer;
M : Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put(M);
end main;
控制台:
$ ./main
1 2 3
4 5 6
或者,如 @SimonWright ,您可以 "remove the New_Line
in Safe_Printer.Put(String)
." 您选择的方法将取决于 Safe_Printer
规范中提供的所需效果。还要考虑限制 use
子句的范围。
您不应从受保护的对象中调用 'potentially blocking operation'。对 Text_IO.Put
的调用是一个潜在的阻塞操作。请参阅 Ada 参考手册第 9.5.1 节。我很惊讶你的编译器实际上没有抱怨。
在这种情况下,您可以做的一件事是使用任务而不是受保护的对象。
例如:
with Ada.Text_IO;
procedure Main is
type Matrix is array (Integer range <>, Integer range <>) of Integer;
task Safe_Printer is
entry Put (S: in String);
entry Put (M: in Matrix);
end Safe_Printer;
task body Safe_Printer is
S: access String;
M: access Matrix;
begin
loop
select
accept Put (S: in String) do
Safe_Printer.S := new String (S'Range);
Safe_Printer.S.all := S;
end;
Ada.Text_IO.Put_Line (S.all);
or
accept Put (M: in Matrix) do
Safe_Printer.M := new Matrix (M'Range (1), M'Range (2));
Safe_Printer.M.all := M;
end;
for I in M'Range (1) loop
for J in M'Range (2) loop
Ada.Text_IO.Put (Integer'Image (M (I, J)) & " ");
end loop;
Ada.Text_IO.New_Line;
end loop;
or
terminate;
end select;
end loop;
end Safe_Printer;
M: Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put (M);
end Main;
这种方法的另一个优点是对 Text_IO.Put[_Line]
的调用实际上是与主任务并行执行的。缺点是(为了安全起见)复制要打印的字符串或矩阵。
此代码的更好版本可能会使用 Unchecked_Deallocation
或 Ada.Containers.Indefinite_Holders
来很好地自行清理。
附加问题:您认为 Main
过程中矩阵 M
的数组边界是什么?
我的问题是我创建了一个受保护的Safe_Printer
;但是当我使用它的过程时,它弄乱了 Put
函数。每次它打印到一个新行。我如何才能避免这种情况?基本上,我想以可读的格式打印我的矩阵。
这是我的代码:
with Ada.Text_IO;
use Ada.Text_IO;
procedure main is
type Matrix is array(integer range <>, integer range <>) of integer;
protected Safe_Printer is
procedure Put(S: String);
procedure Put(M: Matrix);
end Safe_Printer;
protected body Safe_Printer is
procedure Put(S: String) is
begin
for I in S'range loop
Put(S(I));
end loop;
New_Line;
end Put;
procedure Put(M:Matrix) is
begin
for I in m'range(1) loop
for j in m'range(2) loop
put(integer'image(m(i,j)) & " ");
end loop;
new_line(1);
end loop;
end Put;
end Safe_Printer;
m:Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put(m);
for I in m'range(1) loop
for j in m'range(2) loop
put(integer'image(m(i,j)) & " ");
end loop;
new_line(1);
end loop;
end main;
我的输出是:
1
2
3
4
5
6
1 2 3
4 5 6
因为 'Image
属性 returns a String
,您的 Put(M : Matrix)
实现在其内部循环中调用 Safe_Printer.Put(S : String)
;每个矩阵条目然后得到一个 New_Line
。一种解决方案是在 Safe_Printer.Put(M : Matrix)
:
Put
定义的语言
procedure Put(M : Matrix) is
begin
for I in M'range(1) loop
for j in M'range(2) loop
Ada.Text_IO.Put(integer'image(M(i,j)) & " ");
end loop;
New_Line;
end loop;
end Put;
经测试:
with Ada.Text_IO;
use Ada.Text_IO;
procedure main is
type Matrix is array(integer range <>, integer range <>) of integer;
protected Safe_Printer is
procedure Put(S : String);
procedure Put(M: Matrix);
end Safe_Printer;
protected body Safe_Printer is
procedure Put(S : String) is
begin
for I in S'range loop
Put(S(I));
end loop;
New_Line;
end Put;
procedure Put(M : Matrix) is
begin
for I in M'range(1) loop
for j in M'range(2) loop
Ada.Text_IO.Put(integer'image(M(i,j)) & " ");
end loop;
New_Line;
end loop;
end Put;
end Safe_Printer;
M : Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put(M);
end main;
控制台:
$ ./main 1 2 3 4 5 6
或者,如 @SimonWright New_Line
in Safe_Printer.Put(String)
." 您选择的方法将取决于 Safe_Printer
规范中提供的所需效果。还要考虑限制 use
子句的范围。
您不应从受保护的对象中调用 'potentially blocking operation'。对 Text_IO.Put
的调用是一个潜在的阻塞操作。请参阅 Ada 参考手册第 9.5.1 节。我很惊讶你的编译器实际上没有抱怨。
在这种情况下,您可以做的一件事是使用任务而不是受保护的对象。
例如:
with Ada.Text_IO;
procedure Main is
type Matrix is array (Integer range <>, Integer range <>) of Integer;
task Safe_Printer is
entry Put (S: in String);
entry Put (M: in Matrix);
end Safe_Printer;
task body Safe_Printer is
S: access String;
M: access Matrix;
begin
loop
select
accept Put (S: in String) do
Safe_Printer.S := new String (S'Range);
Safe_Printer.S.all := S;
end;
Ada.Text_IO.Put_Line (S.all);
or
accept Put (M: in Matrix) do
Safe_Printer.M := new Matrix (M'Range (1), M'Range (2));
Safe_Printer.M.all := M;
end;
for I in M'Range (1) loop
for J in M'Range (2) loop
Ada.Text_IO.Put (Integer'Image (M (I, J)) & " ");
end loop;
Ada.Text_IO.New_Line;
end loop;
or
terminate;
end select;
end loop;
end Safe_Printer;
M: Matrix := ((1,2,3),
(4,5,6));
begin
Safe_Printer.Put (M);
end Main;
这种方法的另一个优点是对 Text_IO.Put[_Line]
的调用实际上是与主任务并行执行的。缺点是(为了安全起见)复制要打印的字符串或矩阵。
此代码的更好版本可能会使用 Unchecked_Deallocation
或 Ada.Containers.Indefinite_Holders
来很好地自行清理。
附加问题:您认为 Main
过程中矩阵 M
的数组边界是什么?