Jump to content
Wikibooks The Free Textbook Project

Ada Programming/Control

From Wikibooks, open books for an open world

Ada. Time-tested, safe and secure.
Ada. Time-tested, safe and secure.

This computer programming article is available for pseudocode, Ada, and ooc.

Conditionals

[edit | edit source ]

Conditional clauses are blocks of code that will only execute if a particular expression (the condition) is true.

if-else

[edit | edit source ]

The if-else statement is the simplest of the conditional statements. They are also called branches, as when the program arrives at an if statement during its execution, control will "branch" off into one of two or more "directions". An if-else statement is generally in the following form:

if  condition then 
 statement;
else 
 other statement;
end  if ;

If the original condition is met, then all the code within the first statement is executed. The optional else section specifies an alternative statement that will be executed if the condition is false. Exact syntax will vary between programming languages, but the majority of programming languages (especially procedural and structured languages) will have some form of if-else conditional statement built-in. The if-else statement can usually be extended to the following form:

if  condition then 
 statement;
elsif  condition then 
 other statement;
elsif  condition then 
 other statement;
...
else 
 another statement;
end  if ; 

Only one statement in the entire block will be executed. This statement will be the first one with a condition which evaluates to be true. The concept of an if-else-if structure is easier to understand with the aid of an example:

with  Ada . Text_IO ;
use  Ada . Text_IO ;
...
type  Degrees is  new  Float range  -273.15 .. Float'Last;
...
Temperature : Degrees;
...
if  Temperature >= 40.0 then 
 Put_Line ("Wow!");
 Put_Line ("It's extremely hot");
elsif  Temperature >= 30.0 then 
 Put_Line ("It's hot");
elsif  Temperature >= 20.0 then 
 Put_Line ("It's warm");
elsif  Temperature >= 10.0 then 
 Put_Line ("It's cool");
elsif  Temperature >= 0.0 then 
 Put_Line ("It's cold");
else 
 Put_Line ("It's freezing");
end  if ; 

Optimizing hints

[edit source ]

When this program executes, the computer will check all conditions in order until one of them matches its concept of truth. As soon as this occurs, the program will execute the statement immediately following the condition and continue, without checking any other condition . For this reason, when you are trying to optimize a program, it is a good idea to sort your if-else conditions in descending probability. This will ensure that in the most common scenarios, the computer has to do less work, as it will most likely only have to check one or two "branches" before it finds the statement which it should execute. However, when writing programs for the first time, try not to think about this too much lest you find yourself undertaking premature optimization.

Having said all that, you should be aware that an optimizing compiler might rearrange your if statement at will when the statement in question is free from side effects. Among other techniques optimizing compilers might even apply jump tables and binary searches.


In Ada, conditional statements with more than one conditional do not use short-circuit evaluation by default. In order to mimic C/C++'s short-circuit evaluation, use and then or or else between the conditions.

Often it is necessary to compare one specific variable against several constant expressions. For this kind of conditional expression the case statement exists. For example:


case  X is 
 when  1 => 
 -- execute the following if X is 1:
 Walk_The_Dog;
 when  5 => 
 -- execute the following if X is 5:
 Launch_Nuke;
 when  8 | 10 => 
 -- execute the following if X is 8 or 10:
 Sell_All_Stock;
 when  others  => 
 -- execute the following if X is none of the above cases:
 Self_Destruct;
end  case ;

The subtype of X must be a discrete type, i.e. an enumeration, or signed or unsigned integer type.

In Ada, one advantage of the case statement is that the compiler will check the coverage of the choices, that is, all the values of the subtype of variable X must be present or a default branch when others must specify what to do in the remaining cases.

Unconditionals

[edit source ]

Unconditionals let you change the flow of your program without a condition. You should be careful when using unconditionals. Often they make programs difficult to understand. Read Isn't goto evil? for more information.

return

[edit source ]

End a function and return to the calling procedure or function.


For procedures:

return ;

For functions:

return  Value;

goto

[edit | edit source ]

Goto transfers control to the statement after the label.

 goto  Label;
 Dont_Do_Something;
<< Label>> 
 -- ...

The goto statement is not allowed to transfer control in the following conditions:

  • outside a body;
  • between alternatives of a case statement, if statement, or select statement;
  • between different exception handlers; or from an exception handler of a handled_sequence_of_statements back to its sequence_of_statements.

Is goto evil?

[edit | edit source ]

Since Professor Dikstra wrote his article Go To Statement Considered Harmful, goto is considered bad practice in structured programming languages, and, in fact, many programming style guides forbid the use of the goto statement. But it is often overlooked that any return which is not the last statement inside a procedure or function is also an unconditional statement — a goto in disguise. There is an important difference though: a return is a forward only use of goto. Exceptions are also a type of goto statement; and note that they need not specify where they are going to.

Therefore, if you have functions and procedures with more than one return statement you are breaking the structure of the program similarly to a use of goto. In practice, nearly every programmer is familiar with a 'return' statement and its associated behavior; thus, when it comes down to readability the following two samples are almost the same:

procedure  Use_Return is 
begin 
 Do_Something;
 if  Test then 
 return ;
 end  if ;
 Do_Something_Else;
 return ;
end  Use_Return;
procedure  Use_Goto is 
begin 
 Do_Something; 
 
 if  Test then 
 goto  Exit_Use_Goto; 
 end  if ; 
 Do_Something_Else; 
<< Exit_Use_Goto>> 
 return ; 
end  Use_Goto; 

Also, note that the goto statement in Ada is considered safer than in other languages, since it doesn't allow you to transfer control in certain conditions where the control structure is susceptible to be broken.

Because the use of a goto requires the declaration of a label, it can be considered as readable as the use of return. So if readability is a concern instead of a strict programming rule such as "don't use goto", then it is possible to consider the use of goto than multiple return statements. Although, it is best to use the structured approach whenever possible, where neither goto nor multiple returns are needed, for instance:

procedure  Use_If is 
begin 
 Do_Something;
 
 if  not  Test then 
 Do_Something_Else;
 end  if ;
 return ;
end  Use_If;

Loops

[edit source ]

Loops allow you to have a set of statements repeated over and over again.

Endless loop

[edit source ]

The endless loop is a loop which never ends and the statements inside are repeated forever. The term, endless loop, is a relative term; if the running program is forcibly terminated by some means beyond the control of the program, then an endless loop will indeed end.


Endless_Loop :
 loop 
 Do_Something;
 end  loop  Endless_Loop;

The loop name (in this case, "Endless_Loop") is an optional feature of Ada. Naming loops is nice for readability but not strictly needed. Loop names are useful though if the program should jump out of an inner loop, see below.

Loop with condition at the beginning

[edit source ]

This loop has a condition at the beginning. The statements are repeated as long as the condition is met. If the condition is not met at the very beginning then the statements inside the loop are never executed.


While_Loop :
 while  X <= 5 loop 
 X := Calculate_Something;
 end  loop  While_Loop;

Loop with condition at the end

[edit source ]

This loop has a condition at the end and the statements are repeated until the condition is met. Since the check is at the end the statements are at least executed once.


Until_Loop :
 loop 
 X := Calculate_Something;
 exit  Until_Loop when  X > 5;
 end  loop  Until_Loop;

Loop with condition in the middle

[edit source ]

Sometimes you need to first make a calculation and exit the loop when a certain criterion is met. However when the criterion is not met there is something else to be done. Hence you need a loop where the exit condition is in the middle.


Exit_Loop :
 loop 
 X := Calculate_Something;
 exit  Exit_Loop when  X > 5;
 Do_Something (X);
 end  loop  Exit_Loop;

In Ada the exit condition can be combined with any other loop statement as well. You can also have more than one exit statement. You can also exit a named outer loop if you have several loops inside each other.

for loop

[edit source ]

Quite often one needs a loop where a specific variable is counted from a given start value up or down to a specific end value. You could use the while loop here — but since this is a very common loop there is an easier syntax available.


For_Loop :
 for  I in  Integer range  1 .. 10 loop 
 Do_Something (I)
 end  loop  For_Loop;

You don't have to declare both subtype and range as seen in the example. If you leave out the subtype then the compiler will determine it by context; if you leave out the range then the loop will iterate over every value of the subtype given.

As always with Ada: when "determine by context" gives two or more possible options then an error will be displayed and then you have to name the type to be used. Ada will only do "guess-works" when it is safe to do so.

The loop counter I is a constant implicitly declared and ceases to exist after the body of the loop.

for loop on arrays

[edit source ]

Another very common situation is the need for a loop which iterates over every element of an array. The following sample code shows you how to achieve this:


Array_Loop :
 for  I in  X'Range  loop 
 X (I) := Get_Next_Element;
 end  loop  Array_Loop;

With X being an array. Note: This syntax is mostly used on arrays — hence the name — but will also work with other types when a full iteration is needed.

Working example

[edit | edit source ]

The following example shows how to iterate over every element of an integer type.

File: range_1.adb (view, plain text, download page, browse all)
with  Ada . Text_IO ;
procedure  Range_1 is 
 type  Range_Type is  range  -5 .. 10;
 package  T_IO renames  Ada . Text_IO ;
 package  I_IO is  new  Ada . Text_IO . Integer_IO  (Range_Type);
begin 
 for  A in  Range_Type loop 
 I_IO.Put (Item => A,
 Width => 3,
 Base => 10);
 if  A < Range_Type'Last then 
 T_IO.Put (",");
 else 
 T_IO.New_Line;
 end  if ;
 end  loop ;
end  Range_1;

See also

[edit | edit source ]

Wikibook

[edit | edit source ]

Ada Reference Manual

[edit | edit source ]

AltStyle によって変換されたページ (->オリジナル) /