Statements, Declarations, and Control Structures
Statements and Declarations
The following code samples are all equivalent, and illustrate the use of comments and working with integer variables:
[Ada]
--
-- Ada program to declare and modify Integers
--
procedure Main is
-- Variable declarations
A, B : Integer := 0;
C : Integer := 100;
D : Integer;
begin
-- Ada uses a regular assignment statement for incrementation.
A := A + 1;
-- Regular addition
D := A + B + C;
end Main;
[C++]
/*
* C++ program to declare and modify ints
*/
int main(int argc, const char* argv[]) {
// Variable declarations
int a = 0, b = 0, c = 100, d;
// C++ shorthand for incrementation
a++;
// Regular addition
d = a + b + c;
}
[Java]
/*
* Java program to declare and modify ints
*/
public class Main {
public static void main(String [] argv) {
// Variable declarations
int a = 0, b = 0, c = 100, d;
// Java shorthand for incrementation
a++;
// Regular addition
d = a + b + c;
}
}
Statements are terminated by semicolons in all three languages. In Ada, blocks of code are surrounded by the reserved words begin
and end
rather than by curly braces. We can use both multi-line and single-line comment styles in the C++ and Java code, and only single-line comments in the Ada code.
Ada requires variable declarations to be made in a specific area called the declarative part, seen here before the begin
keyword. Variable declarations start with the identifier in Ada, as opposed to starting with the type as in C++ and Java (also note Ada's use of the :
separator). Specifying initializers is different as well: in Ada an initialization expression can apply to multiple variables (but will be evaluated separately for each), whereas in C++ and Java each variable is initialized individually. In all three languages, if you use a function as an initializer and that function returns different values on every invocation, each variable will get initialized to a different value.
Let's move on to the imperative statements. Ada does not provide ++
or --
shorthand expressions for increment/decrement operations; it is necessary to use a full assignment statement. The :=
symbol is used in Ada to perform value assignment. Unlike C++'s and Java's =
symbol, :=
can not be used as part of an expression. So, a statement like A := B := C;
doesn't make sense to an Ada compiler, and neither does a clause like if A := B then ...
. Both are compile-time errors.
You can nest a block of code within an outer block if you want to create an inner scope:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
begin
Put_Line ("Before the inner block");
declare
Alpha : Integer := 0;
begin
Alpha := Alpha + 1;
Put_Line ("Now inside the inner block");
end;
Put_Line ("After the inner block");
end Main;
It is OK to have an empty declarative part or to omit the declarative part entirely — just start the inner block with begin
if you have no declarations to make. However it is not OK to have an empty sequence of statements. You must at least provide a null;
statement, which does nothing and indicates that the omission of statements is intentional.
Conditions
The use of the if
statement:
[Ada]
if Variable > 0 then
Put_Line (" > 0 ");
elsif Variable < 0 then
Put_Line (" < 0 ");
else
Put_Line (" = 0 ");
end if;
[C++]
if (Variable > 0)
cout << " > 0 " << endl;
else if (Variable < 0)
cout << " < 0 " << endl;
else
cout << " = 0 " << endl;
[Java]
if (Variable > 0)
System.out.println (" > 0 ");
else if (Variable < 0)
System.out.println (" < 0 ");
else
System.out.println (" = 0 ");
In Ada, everything that appears between the if
and then
keywords is the conditional expression — no parentheses required. Comparison operators are the same, except for equality (=
) and inequality (/=
). The English words not
, and
, and or
replace the symbols !
, &
, and |
, respectively, for performing boolean operations.
It's more customary to use &&
and ||
in C++ and Java than &
and |
when writing boolean expressions. The difference is that &&
and ||
are short-circuit operators, which evaluate terms only as necessary, and &
and |
will unconditionally evaluate all terms. In Ada, and
and or
will evaluate all terms; and then
and or else
direct the compiler to employ short circuit evaluation.
Here are what switch/case statements look like:
[Ada]
case Variable is
when 0 =>
Put_Line ("Zero");
when 1 .. 9 =>
Put_Line ("Positive Digit");
when 10 | 12 | 14 | 16 | 18 =>
Put_Line ("Even Number between 10 and 18");
when others =>
Put_Line ("Something else");
end case;
[C++]
switch (Variable) {
case 0:
cout << "Zero" << endl;
break;
case 1: case 2: case 3: case 4: case 5:
case 6: case 7: case 8: case 9:
cout << "Positive Digit" << endl;
break;
case 10: case 12: case 14: case 16: case 18:
cout << "Even Number between 10 and 18" << endl;
break;
default:
cout << "Something else";
}
[Java]
switch (Variable) {
case 0:
System.out.println ("Zero");
break;
case 1: case 2: case 3: case 4: case 5:
case 6: case 7: case 8: case 9:
System.out.println ("Positive Digit");
break;
case 10: case 12: case 14: case 16: case 18:
System.out.println ("Even Number between 10 and 18");
break;
default:
System.out.println ("Something else");
}
In Ada, the case
and end case
lines surround the whole case statement, and each case starts with when
. So, when programming in Ada, replace switch
with case
, and replace case
with when
.
Case statements in Ada require the use of discrete types (integers or enumeration types), and require all possible cases to be covered by when
statements. If not all the cases are handled, or if duplicate cases exist, the program will not compile. The default case, default:
in C++ and Java, can be specified using when others =>
in Ada.
In Ada, the break
instruction is implicit and program execution will never fall through to subsequent cases. In order to combine cases, you can specify ranges using ..
and enumerate disjoint values using |
which neatly replaces the multiple case
statements seen in the C++ and Java versions.
Loops
In Ada, loops always start with the loop
reserved word and end with end loop
. To leave the loop, use exit
— the C++ and Java equivalent being break
. This statement can specify a terminating condition using the exit when
syntax. The loop
opening the block can be preceded by a while
or a for
.
The while
loop is the simplest one, and is very similar across all three languages:
[Ada]
while Variable < 10_000 loop
Variable := Variable * 2;
end loop;
[C++]
while (Variable < 10000) {
Variable = Variable * 2;
}
[Java]
while (Variable < 10000) {
Variable = Variable * 2;
}
Ada's for
loop, however, is quite different from that in C++ and Java. It always increments or decrements a loop index within a discrete range. The loop index (or "loop parameter" in Ada parlance) is local to the scope of the loop and is implicitly incremented or decremented at each iteration of the loop statements; the program cannot directly modify its value. The type of the loop parameter is derived from the range. The range is always given in ascending order even if the loop iterates in descending order. If the starting bound is greater than the ending bound, the interval is considered to be empty and the loop contents will not be executed. To specify a loop iteration in decreasing order, use the reverse
reserved word. Here are examples of loops going in both directions:
[Ada]
-- Outputs 0, 1, 2, ..., 9
for Variable in 0 .. 9 loop
Put_Line (Integer'Image (Variable));
end loop;
-- Outputs 9, 8, 7, ..., 0
for Variable in reverse 0 .. 9 loop
Put_Line (Integer'Image (Variable));
end loop;
[C++]
// Outputs 0, 1, 2, ..., 9
for (int Variable = 0; Variable <= 9; Variable++) {
cout << Variable << endl;
}
// Outputs 9, 8, 7, ..., 0
for (int Variable = 9; Variable >=0; Variable--) {
cout << Variable << endl;
}
[Java]
// Outputs 0, 1, 2, ..., 9
for (int Variable = 0; Variable <= 9; Variable++) {
System.out.println (Variable);
}
// Outputs 9, 8, 7, ..., 0
for (int Variable = 9; Variable >= 0; Variable--) {
System.out.println (Variable);
}
Ada uses the Integer
type's 'Image
attribute to convert a numerical value to a String. There is no implicit conversion between Integer
and String
as there is in C++ and Java. We'll have a more in-depth look at such attributes later on.
It's easy to express iteration over the contents of a container (for instance, an array, a list, or a map) in Ada and Java. For example, assuming that Int_List
is defined as an array of Integer values, you can use:
[Ada]
for I of Int_List loop
Put_Line (Integer'Image (I));
end loop;
[Java]
for (int i : Int_List) {
System.out.println (i);
}