ADA 95教程 控制结构1

ADA中最简单的循环LOOP

Example program ------> e_c05_p1.ada

 -- Chapter 5 - Program 1
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure LoopDemo is

   Index, Count : INTEGER;

begin
   Index := 1;
   loop                            -- This is the simplest loop
      Put("Index =");
      Put(Index, 5); New_Line;
      Index := Index + 1;
      exit when Index = 5;
   end loop;

   Index := 1;
   loop                            -- Another simplest loop
      Put("Index =");
      Put(Index, 5); New_Line;
      Index := Index + 1;
      if Index = 5 then exit; end if;
   end loop;

   Count := 1;
   while Count < 5 loop            -- This is the while loop
      Put("Count =");
      Put(Count, 5); New_Line;
      Count := Count + 1;
   end loop;

   for Index in 1..4 loop          -- This is the for loop
      Put("Doubled index =");
      Put(2 * Index, 5); New_Line;
   end loop;

   for Count in reverse 5..8 loop  -- This is the reverse for loop
      Put("Triple count =");
      Put(3 * Count, 5); New_Line;
   end loop;

   for Index in 7..11 loop         -- An empty loop
      null;
   end loop;

end LoopDemo;




-- Result of execution

-- Index =    1
-- Index =    2
-- Index =    3
-- Index =    4
-- Index =    1
-- Index =    2
-- Index =    3
-- Index =    4
-- Count =    1
-- Count =    2
-- Count =    3
-- Count =    4
-- Doubled index =    2
-- Doubled index =    4
-- Doubled index =    6
-- Doubled index =    8
-- Triple count =   24
-- Triple count =   21
-- Triple count =   18
-- Triple count =   15

 我们将从Ada中最简单的循环开始,无限循环,在程序e\u c05\u p1.Ada的第11行到第16行中有说明。名为Index的变量在进入循环之前被初始化为值1,循环本身在第11到16行中给出。循环以保留字loop开始,以两个保留字end loop循环结束。任意数量的可执行语句被放置在这两个分隔符之间,循环不断重复,直到有什么东西导致程序跳出循环。在这种情况下,每次通过循环时,变量索引都会递增,当它达到值5时,执行exit语句,这将导致控制跳出循环,并在循环结束后立即开始执行指令。单词exit和when是另外两个保留单词。

exit后面的表达式必须计算为布尔结果,,当结果为TRUE时,将退出循环,但只要结果为FALSE,循环将继续执行。请注意,exit语句可以放置在循环中的任何位置,并且可以根据需要在循环中放置尽可能多的条件出口。

第18行到第24行中的语句使用循环出口的另一种形式,它使用我们尚未研究的if语句。if形式的exit是一种非常常见的用法,因此这里必须将它作为最简单的循环类型之一包含进来。请注意,if出口可以放置在循环中的任何位置,并且可以根据需要在循环中使用尽可能多的出口。if语句将在本章后面进行详细解释。

 

退出声明

15号线的出口和23号线的出口有细微的区别。第15行中的退出是有条件的,因为只有当条件的计算结果为TRUE时才会执行。然而,第23行中的退出是无条件的,因为只要控制流程到达exit,就可以执行退出。请记住,exit仅用于退出循环,它不用于Ada中的任何其他构造。

 

while循环

while循环与LOOP循环相同,只是在保留字循环之前添加了一个测试。测试是在循环开始时完成的,因此它比LOOP循环的通用性稍差,但它还需要一个布尔表达式作为构造的一部分。本程序的第27行到第31行说明了这个循环。在第27行中,“while Count<5”称为迭代子句。

 

for循环

到目前为止,在这个示例程序中研究的循环使用了不确定的通过次数,因为它们在通过循环时计算自己的极限。需要指出的是,布尔表达式在循环的每次传递中都会被求值。然而,for循环的极限值被计算了一次,并且在循环的第一次传递开始之前,通过循环的次数被完全定义。

for循环在第33行到第36行中示出,其中控制由保留字循环之前的几个字组成。在这种情况下,循环控制是变量索引,变量的范围是1到4。循环将执行四次,每次都有一个更大的变量索引,因为循环索引总是递增一。Ada中没有任何其他价值的增加规定。for和in的保留字以显示的方式用于所有for循环。它们用于括起循环索引(在本例中称为index)和索引范围(在本例中为1到4)。

由于INTEGER类型通常用于循环索引,因此如果没有明确说明该类型,它将默认为INTEGER类型。这使得编写大多数循环更加容易。

注意,循环参数不需要是INTEGER类型,但是循环索引和两个范围限制必须是同一类型。还要注意循环迭代器的值在循环终止后不可用。循环完成后,循环迭代器将完全不存在。(当我们完成下一个示例程序的学习时,我们将看到这是有充分理由的。)

 

反循环

第38行到第41行中所示的for循环略有变化,其中循环索引在每次通过逻辑时都会减小。单词reverse是另一个保留字,用于指示此循环的向后计数性质。请注意,范围是以升序表示的,但实际执行从8开始,每次执行时按1递减,直到达到5为止,在循环中通过Count设置为5后退出。

 

空循环

继续在名为e_c05_p1.ada的程序中,第43行到第45行中的循环被给出,以说明可以编写一个完全不做任何事情的循环。这似乎是一件愚蠢的事情,但在使用任务分配时,有必要在循环中什么都不做。在这一点上,更重要的是要说明Ada是如此的挑剔,你不能写一个什么都没有的循环,但是你必须告诉编译器,你真的想让循环什么都不做,把保留字null作为一个语句包含在循环中。

一定要编译和执行这个程序,并确保您完全理解每个循环的作用。

 

语句稍微复杂一些

Example program ------> e_c05_p2.ada

 -- Chapter 5 - Program 2
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure MoreLoop is

   type MY_TYPE is range 10..13;

   package My_Int_IO is new Ada.Text_IO.Integer_IO(MY_TYPE);
   use My_Int_IO;

   My_Range      : MY_TYPE;
   TWO           : constant INTEGER := 2;
   THREE         : constant INTEGER := 3;
   FOUR          : constant INTEGER := 4;
   Height,Width  : INTEGER;
   Special_Index : INTEGER;

begin

   for Index in MY_TYPE loop
      Put("Going through the first loop");
      Put(Index, 3);
      New_Line;
   end loop;

   for Index in MY_TYPE'FIRST..MY_TYPE'LAST loop
      Put("Going through the second loop");
      Put(Index, 3);
      New_Line;
   end loop;

   for Index in TWO..THREE**2 - FOUR loop    -- range is 2..5
      Put("Going through the third loop");
      Put(Index, 3);
      New_Line;
   end loop;

Named_Loop:
   for Height in TWO..FOUR loop
      for Width in THREE..5 loop
         if Height * Width = 12 then
            exit Named_Loop;
         end if;
         Put("Now we are in the nested loop and area is");
         Put(Height*Width, 5);
         New_Line;
      end loop;
   end loop Named_Loop;

   Special_Index := 157;
   for Special_Index in 3..6 loop
      Put("In the Special Index loop");
      Put(Special_Index, 5);
      New_Line;
   end loop;
   Put("The Special Index loop is completed");
   Put(Special_Index, 5);
   New_Line;

end MoreLoop;




-- Result of execution

-- Going through the first loop 10
-- Going through the first loop 11
-- Going through the first loop 12
-- Going through the first loop 13
-- Going through the second loop 10
-- Going through the second loop 11
-- Going through the second loop 12
-- Going through the second loop 13
-- Going through the third loop  2
-- Going through the third loop  3
-- Going through the third loop  4
-- Going through the third loop  5
-- Now we are in the nested loop and area is    6
-- Now we are in the nested loop and area is    8
-- Now we are in the nested loop and area is   10
-- Now we are in the nested loop and area is    9
-- In the Special Index loop    3
-- In the Special Index loop    4
-- In the Special Index loop    5
-- In the Special Index loop    6
-- The Special Index loop is completed  157

 检查名为e_c05_p2.ada的程序,以获得一些更复杂但更通用的for循环示例。循环说明了Ada中设计的一些灵活性,以允许更高效的编程。第21行到第25行中的第一个示例有两个新概念,第一个是循环变量Index没有在程序的定义部分声明,第二个是范围由类型定义,而不是变量或常量限制。

考虑到第一点,for循环中的循环索引不需要显式声明,而是由程序隐式声明,在循环期间使用,并在循环终止时丢弃。循环终止后,循环索引的最终值不可使用,无论该索引是显式声明还是隐式声明,都是如此。(我们很快就会看到,它总是由Ada系统隐式声明的。)Ada语言的设计者让编译器编写者自由地了解循环索引是如何递增的以及何时递增的,而不是指定最终的值是什么。要记住的一条简单规则是,在终止循环时不能依赖于循环索引的最终值。如果需要最终值,则必须在离开循环之前将其复制到其他变量中。

 

对循环范围使用类型指定

上面提到的第二点是,循环范围是作为一个类型给出的。给定的类型MY_TYPE的定义范围是10..13,因此查看循环索引范围应该没有实际问题。此外,名为index的隐式循环索引也将是myu类型。因为我们希望在每次通过循环的过程中打印循环索引的值,所以我们在第9行和第10行中为MY_TYPE实例化一个Integer_IO包的副本。

必须强调这个程序中第一个循环的最后一点。此for循环中的循环索引以及任何for循环中的循环索引都将被视为循环中的常量,因此不能为其指定新值。循环机制本身是唯一可以改变循环索引值的方法。

 

我们使用的第一个属性

在第3章中,我们简要介绍了属性,但并没有真正介绍它们的用法。在第27行到第31行的循环中,我们再次将范围定义为类型MY_TYPE的限制,但这次我们使用属性显式地命名了类型的第一个和最后一个值。第21行中描述的方法更简洁,但两种方法得到的结果相同。例如,如果要从第一个元素循环到某个中点,则第二个方法提供了使用范围的某个端点的方法。

 

计算的循环范围限制

第33行到第37行中的循环的范围限制不是静态的,而是在进入循环时计算的。在这种情况下,计算都是基于常量,但它们可以基于任意复杂度的变量。如果它们是基于一个或多个变量,有一个微妙的点,你必须明白。如果一个或多个变量在循环中发生变化,则范围不会相应地变化,因为在进入循环时,循环范围限制只计算一次。

应该清楚的是,对于这个特殊的循环,循环范围是2到5。

 

双嵌套for循环

第39行到49行包含两个嵌套的循环,并将其添加到外部循环。标识符Named_Loop是应用于外部循环的循环名称。该名称出现在循环开始之前,并且还跟随该循环的相应结束循环。这将导致命名循环。在第42行和第43行中,我们有一个条件语句,它表示如果高度和宽度的乘积等于12,我们将退出Named_Loop的循环。如果没有给定的名称,我们只会退出当前有效的循环,即由循环索引宽度定义的内部循环,但是由于我们提到了这个名称,我们用给定的名称退出循环,并退出两个循环。通过向循环添加名称,可以退出任意多个嵌套级别,只需使用一个exit语句。

 

近距离观察循环索引

在第51行中,我们将值157赋给名为Special_Index的变量,并将该变量名用于下面循环中的循环索引。循环终止后,我们显示变量的值以查看最终值是什么,当我们运行程序时,我们发现该值与指定的值没有变化,即157。这表明,即使我们认为我们显式地定义了循环索引变量,系统实际上是在构造一个全新的变量,使用它,并在循环终止后丢弃它。Ada将循环变量定义为一个自动变量,在需要时生成,在不再需要时丢弃。更多关于自动变量的内容将在后面讨论。要从中理解的重要一点是Ada隐式地为我们声明了所有循环变量。

 

 

 

---------------------------------------------------------------------------------------------------------------------------

原英文版出处:https://perso.telecom-paristech.fr/pautet/Ada95/a95list.htm

翻译(百度):博客园  一个默默的 *** 的人

posted @ 2021-03-26 07:24  yangjianfeng  阅读(86)  评论(0编辑  收藏  举报