Ada之常見控制語句介紹

2018-11-13 12:50 更新

 概述(Overview)

    在 Ada 子程序的 “is”和“end”之間,是一組有序語句,每句用雙引號;結(jié)束。這些語句大致可分成三種控制結(jié)構(gòu):順序結(jié)構(gòu),選擇結(jié)構(gòu),循環(huán)結(jié)構(gòu)----如果按照前輩們辛辛苦苦的證明:任何程序都可以只由這三種結(jié)構(gòu)完成。以前我們見過的簡單程序都是順序結(jié)構(gòu),本章里會介紹一下 Ada 里選擇結(jié)構(gòu)的if、case 語句和循環(huán)結(jié)構(gòu)的 loop 語句及其變種,并介紹順序結(jié)構(gòu)中以前沒講過的 null 和塊語句(block statement),最后是比較有爭議的 goto 語句---好像每本教科書上都罵它,說它打破了程序的良好結(jié)構(gòu)。控制結(jié)構(gòu)是一門老話題,Ada95 對它也沒作多大改動,語法上和其它語言還是很接近的,但可讀性好一點,所有控制結(jié)構(gòu)后都以"end something"結(jié)束。

if 語句(if statement)

   if 語句判斷一個條件是否成立,如果成立,則執(zhí)行特定的語句,否則跳過這些語句。一般格式如下:

if condition then
      statements
end if;

   當 condition 的值為 True 時,則執(zhí)行 statements,否則跳過 statements,執(zhí)行“end if”后面的語句。

   如果當 condition 為 False 也要執(zhí)行特定語句,則用下面的格式:

if condition then
     statements
else
       other statements
end if;

   這樣當條件不成立時,執(zhí)行other statement,而不是跳過 if 結(jié)構(gòu)。

   下面一種格式是為了多個條件判斷而用,防止 if 語句過多:

if condition then
   statements
elsif condition then
  other statements
elsif condition then
   more other statements
else
  even more other statements
end if;

    使用 elsif 的次數(shù)沒有限制,注意 elsif 的拼寫----不是elseif。在這里需要注意一下condition 的值,一定要為布爾型,不像 C 里面,隨便填個整數(shù)也沒事。

    下面以簡單的一個例子來解釋一下 if 語句:

000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure testrange is
004       Var : Integer;

005 begin
006       Put ("Enter an Integer number to confirm its range:");
007       Get (Var);

008      if Var in Integer'First .. -1 then
009             Put_Line ("It is a negative number");
010      elsif Var in 1 .. Integer'Last then
011            Put_Line ("It is a positive number");
012      else
013             Put_Line ("It is 0");
014      end if;
015 end testrange; 
[007] 輸入值 Var;[008]-[014]的語句都是測試 Var 的范圍,如是負數(shù)則輸出"It is a negative number",正數(shù)輸出"It is a positive number",為0則輸出"It is 0",以上3種情況如果都沒產(chǎn)生,則是因為輸入值非 Integer 類型或輸入值過大,從而產(chǎn)生異常。

 case 語句(case Statement)

    如果所要判斷的變量有多種可能,并且每種情況都要執(zhí)行不同的操作,if 語句很顯然繁了一點,這時就使用 case 語句,格式為:

case expression is
   when choice1 => statements
   when choice2 => statements
     . . .
   when others => statements
end case;

    判斷 expression 的值,如符合某項choice,則執(zhí)行后面的statement,如果全都不符合時,就執(zhí)行 others 后的語句。choice 的值不能相同。when others 也可以沒有,但不推薦這樣做,以免有沒估計到的情況產(chǎn)生。因此上例也可改成:

000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure testrange is
004     Var : Integer;
005 begin
006        Put ("Enter an Integer number to confirm its range:");
007        Get(Var);
008     case Var is
009          when Integer'First .. -1 =>
010                                        Put_Line ("It is a negative number");
011       when 1 .. Integer'Last =>
012                     Put_Line ("It is a positive number");
013       when others =>
014                     Put_Line ("It is 0");
015    end case; 
016 end testrange;

與前面的例子完全等效。

loop 語句(loop Statement)

    很多情況下,我們要反復執(zhí)行同一操作,無疑這時要使用循環(huán)結(jié)構(gòu)。循環(huán)結(jié)構(gòu)除了最簡單的loop語句,還有其變種for 和while語句。

    最簡單的loop語句格式為:

loop 
   statements
end loop; 

    當要退出該循環(huán)時,使用 exit 或 exit when 語句。exit表示直接退出該循環(huán),exit when則在符合 when 后面的條件時再退出。再將testrange 改動一下,來了解loop和exit語句。

000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure testrange is
004     Var : Integer; 
005 begin
006    loop
007        Put ("Enter an Integer number to confirm its range:"); 
008        Get(Var);
009       case Var is
010          when Integer'First .. -1 =>
011                         Put_Line ("It is a negative number"); 
012          when 1 .. Integer'Last =>
013                         Put_Line ("It is a positive number");
014          when others =>
015                         Put_Line ("It is 0");
016       end case; 
017       exit when Var = 0;
018    end loop;
019 end testrange;

上例循環(huán)輸出"Enter an Integer number to confirm its range:",要求輸入一個整數(shù);當輸入值為0時,輸出"it is 0",再退出。

for 循環(huán)(for loop)

    for 循環(huán)只是loop的變種,格式如下:

for index in [reverse] range loop
    statements;
end loop;
*reverse 是可選的.

    注意一下,index 是for循環(huán)中的局部變量,無需額外聲明,只需填入一個合法的標識符即可,在for循環(huán)內(nèi),不能修改index的值。index的值一般情況下是遞增加1,如 for i in 1..100,i的初值為1,每循環(huán)一次加1,直至加到100,循環(huán)100次結(jié)束;有時也需要倒過來,如i初值為100,減到1,則為 for i in reverse 1..100。但range中較大值在前則該循環(huán)不進行,如 for i in [reverse]100..1,循環(huán)內(nèi)語句會略過---即變成了空語句。

    仍舊是通過修改testrange來了解for:

000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure testrange is
004     Var : Integer; 
005 begin
006    for i in 1..10 loop
007        Put ("Enter an Integer number to confirm its range:"); 
008        Get(Var);
009       case Var is
010          when Integer'First .. -1 =>
011                      Put_Line ("It is a negative number"); 
012          when 1 .. Integer'Last =>
013                      Put_Line ("It is a positive number");
014          when others =>
015                      Put_Line ("It is 0");
016       end case; 
017       exit when Var = 0;
018    end loop;
019 end testrange;

如果不輸入0,在輸入10次整數(shù)后,該程序會自動結(jié)束。

 while 循環(huán) (while loop)

 while 循環(huán) (while loop)

    while 循環(huán)則在某條件不成立時結(jié)束循環(huán),其格式為:

while condition loop
    statements
end loop;

    condiotion 和 if 語句中的 condition 一樣,都要求為布爾值,在其值為 False 時,循環(huán)結(jié)束。

    還是老套的testrange:

000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure testrange is
004     Var : Integer; 
005 begin
006    while Var /= 0 loop
007        Put ("Enter an Integer number to confirm its range:"); 
008        Get(Var);
009       case Var is
010          when Integer'First .. -1 =>
011                      Put_Line ("It is a negative number"); 
012           when 1 .. Integer'Last =>
013                      Put_Line ("It is a positive number");
014          when others =>
015                      Put_Line ("It is 0");
016       end case; 
017    end loop;
018 end testrange;

這里取消了exit when語句,由while語句來檢測Var的值。當Var值為0時,循環(huán)結(jié)束。

 null 語句(null Satement)

    null 語句所做的事就是不做事,大部份情況下就等于沒寫;但在一些情況下,還是有其作用,如if var > 0 then null end if,如果沒有 null,則屬于語法錯誤,缺少了語句。因此 null 用在語法上要求必須有語句,但又不想讓程序干什么事的時候。

塊語句(Block Statement)

    塊語句(block statement),就是以一組語句為單位,當作一個獨立的塊,也常用在循環(huán)中,格式為;

identifier:
    [declare]
   begin
        statements
    end indentifier;
declare是可選的,如:
Swap:
  declare
      Temp :Integer;
  begin
      Temp := V; V:=U; U:=Temp;
  end Swap;

    其中的Temp為局部變量,Swap 外的語句無法訪問它,Temp也可寫成Swap.Temp,以此從形式上區(qū)分局部變量和全局變量。塊語句的用法,還是通過實例來講解方便:

000 -- filename: swap.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure Swap is
004     V:Integer := 1;
005     U:Integer := 2;
006 begin
007     PutVU1:
008       begin 
009             Put("V is:"); Put(V); New_Line;
010             Put("U is:"); Put(U); New_Line;
011       end PutVU1; 
012     Swap:
013       declare 
014           Temp :Integer;
015       begin
016           Temp := V; V:=U; U:=Temp;
017       end Swap; 
018     Put_Line ("After swap");
019     PutVU2:
020       begin 
021             Put("V is:"); Put(V); New_Line;
022             Put("U is:"); Put(U); New_Line;
023    end PutVU3; 
024 end Swap;

通過上面的例子,大家可能感覺沒什么意思,塊結(jié)構(gòu)可有可無---反正還是按語句的先后順序執(zhí)行。但如果它用在循環(huán)結(jié)構(gòu)中,則還有點用處:

Main_Circle:
   begin
   loop
       statements;
      loop 
          statements;
         exit Main_Circle when Found;--* 如果 Found 為 True,則跳出 Main_Circle,而不是該句所在的小循環(huán)
          statements;
      end loop;
       statements;
   end loop;
end Main_Circlel;

這樣就能跳出一堆嵌套循環(huán),接下去執(zhí)行的語句都在跳出的循環(huán)后面。

5.9 Goto語句(Goto Statement)

    goto 語句能直接跳到程序的某一處開始執(zhí)行,使程序結(jié)構(gòu)松散很多,有關(guān)編程的教材基本上將它作為碰都不能碰的東西。但在處理異常情況中,goto 還是很方便的---并被有些權(quán)威人士推薦;只要別濫用就可以了。Ada 里goto語句格式為:

<<Label>>
   statements;
goto Label;

如將上例改為:

000 -- filename: swap.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure Swap is
004     V:Integer := 1;
005     U:Integer := 2;
006 begin
007    <<restart>>
008       PutVU1:
009         begin 
010               Put("V is:"); Put(V); New_Line;
011               Put("U is:"); Put(U); New_Line;
012         end PutVU1; 
013       Swap:
014         declare 
015               Temp :Integer;
016         begin
017               Temp := V; V:=U; U:=Temp;
018          end Swap; 
019       Put_Line ("After swap");
020       PutVU2:
021         begin 
022               Put("V is:"); Put(V); New_Line;
023               Put("U is:"); Put(U); New_Line;
024         end PutVU2;
025    goto restart; 
026 end swap;

快到程序結(jié)尾時,又返回到開頭<<restart>>處,因此成了無限循環(huán)。goto語句在 Ada 里的限制還是挺多的,如不能跳到if,case,for,while里面和其所在子程序外。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號