Whirlwind Tour of Ada - Part 3
Structured Statements, Arrays, Procedures
Parameter Modes, Numeric Input, Exceptions
If statement, For loop, Numeric input with Get (getcountpzn.adb)
- Demonstrates if statements, for loops, and the integer
get routine:
getcountpzn.adb and prettified
- Things to note:
- Type Natural is a subtype of the integers (ie 0 .. Integer'last)
- Use Natural when counting
- Natural is a subtype: it is a subset of the values in the type
Integer
- a variable of type Natural can be used anywhere a variable of type
Integer is expected (what does this sound like?)
- Constants must be initialized and can't appear on the
left of an assignment
- Assign multiple values in a single declaration
- Integer.text_io.get: See below
- For loop
- Parens not needed around condition
- For loop specifies precise range of values taken by loop variable
- Loop variable is implicitly declared
- Loops are marked with
loop ... end loop;
- End if required even if body has one statement
- If statements:
- Parens not needed around condition
- Syntax:
if ... elsif ... else ... end if
- else is optional
- any number of elsif can be used
- End if required even if body has one statement
More on Ada.Integer_text_io.get (geteofcountpzn.adb)
-
Ada.Integer_Text_io.get(v)
reads an integer from standard input and stores the value of that integer into variable
v
- Needed to read integers, as integers
-
Get reads from standard input (see below for more info on
standard input)
- A call to
Get skips white space until it finds an integer (or
an error occurs)
- Exceptions than can occur with a call to get:
- If eof is reached before a number is found, an END_ERROR exception occurs.
- If a non-numeric character is found, a DATA_ERROR exception occurs.
Standard Input
While loop and End of File test (geteofcountpzn.adb)
- Demonstrates while loop and the end of file test:
geteofcountpzn.adb and prettified
- Example showing basic structure for testing for end of file:
with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
procedure eofloop is
i: Integer;
begin
while not ada.text_io.end_of_file loop
get(i);
put(i);
new_line;
end loop;
end eofloop;
When doing interactive I/O, end_of_file will return true when you enter
- control-D (linux and unix)
- control-Z [on a line by itself] (windows)
Things to note:
- ada.text_io.end_of_file
- Loop structure: loop ... end loop;
- How to do redirection
Character Input
- If c is declared as
c: Character, then get(c) reads
exactly one character.
- Example program (prettified)
- The example inputs and outputs characters and inputs an integer.
- The output is a line containing the following:
a single character, a character repeated a given number of
times, and a final character.
- If the final character is a 'u', then all of the characters are output in upper case.
- Input specification:
- Specification for each input line is as follows:
- a character that is the first character to output
- the number of times to repeat the middle character
- a character that is the character to output in the middle
- a character that is the last character to output (and the key for upper case output)
- The last character also specifies whether to convert output to upper case
- The program runs until end of file
- Sample input:
A 11bc
1 11b2
1 11 2
a 11bu
a11bx
The input file above will produce the folowing output:
Abbbbbbbbbbbc
1bbbbbbbbbbb2
1 2
ABBBBBBBBBBBU
abbbbbbbbbbbx
done
Execution: If the data is in repeat_middle.txt, then run with
repeat_middle < repeat_middle.txt
Arrays and Array Types (countposzeroneg.adb)
- Demonstrates Arrays and Array Types:
countposzeroneg.adb and prettified
- Things to note:
- The program defines a new type for the array
-
Int_Array is a type; theNums is an array
variable
- Arrays can be assigned using an aggregate assignment (ie the list in
parentheses is an aggregate value)
Using Procedures and Functions (With Array Parameters) (sumcountprocs.adb)
- Demonstrates breaking CountPosZeroNeg into separate routines?
- Use procedures and functions to sum and count positives, etc.:
sumcountprocs.adb
and
prettified
- Things to note:
-
Order of declarations: constants and types, procedures and functions,
variables for main routine
- Must define before use!
- Variables declared inside procedures are called local variables
- Where are the variables for sumcountprocs?
- Functions are like java methods with non-void return types
- Procedures are similar to methods with void return type
- However, procedures can have out mode parameters that return
values to the caller (see below)
Parameter Modes (sumcountprocs.adb continued)
- Parameters have modes that specify the direction the values flow
- Possible parameter modes: In, Out, and In Out
- In: values passed from caller to called
- Out: values passed from called back to caller
- In Out: values passed from caller to called, and back!
- In Mode is the default
- Using a Structure Chart helps thinking about direction of
information flow
- What is the mode of the parameter for get?
More on Parameter Modes
- What kinds of errors could we detect:
- Attempting to assign a value to an in mode parameter
- Not assigning a value to an out mode parameter
- Attempting to change an in mode parameter by calling a procedure
- In mode parameters are treated like constants in the procedure:
procedure foo1(i: in Integer) is
begin
i := 3; -- error
Out mode parameters are uninitialized on entering the procedure:
procedure foo2(o: out Integer) is
j: Integer := o + 1; -- compiles, but erroneous
Out mode parameters must be given a value
procedure foo3(o: out Integer) is
begin
null;
end foo; -- compiles but erroneous
An in mode (formal) parameter can not be passed as an out mode (actual) parameter
procedure foo4(o: out Integer) is
begin
null;
end foo4;
procedure foo5(i: in Integer) is
begin
foo4(i); -- compilation error
To avoid side effects, only procedures can use out and in out mode. Functions can only
have in parameters (more later)
Filling the array using integer_text_io.Get (sumcountprocs2.adb)
Scope
- Basic rule: a declaration is visible from the end of the definition to
the corresponding end statement
- Need some examples
Global Variables
- Definition: A variable is global to a block if it is visible in the
block but not declared in the block
- Important rule: Avoid global variables
- Why: They increase coupling, making debugging difficult
- Need an example:
- Global constants and types are allowed
- Global variables are allowed in certain special cases (eg debug)
More on Exceptions
- Common Exceptions:
- Data error: numeric get reached a non-number
- End error: numeric get reached end of file
- Constraint error: operation applied to invalid value
- Example: array index out of range
- Example: assigning a negative value to a natural number
- Handling exceptions: Any begin/end block can have an exception handler
- Example:
procedure demo_exceptions is
i: natural;
begin
get(i);
-- do something with i
exception
when data_error => put_line("found non-numeric input ");
when end_error => put_line("end of file reached");
when constraint_error => put_line("integer not a natural");
end demo_exceptions;
Can insert extra begin/end when needed
Begin/End Blocks
- Begin/end blocks can be added to allow for exception handling
with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
procedure eofloop is
i: Integer;
begin
while not ada.text_io.end_of_file loop
begin
get(i);
put(i);
new_line;
exception
when data_error => put_line("You must enter a number ");
when constraint_error => put_line("You must enter a natural number");
end
end loop;
end eofloop;
Like java try/catch blocks
Can also use a declare with a begin/end block (see below)
Declare Blocks
- Variables can be declared anywhere - with a declare/begin/end block
- Example:
procedure declare_example is
size: natural;
begin
get(size);
declare
a: array(1 .. size) of Integer;
begin
for i in a'range loop
get(a(i));
end loop;
end;
end declare_example;
Declare Blocks and Unconstrained Arrays
- Unconstrained arrays allow definition of array types whose index range is
assigned later
- Example:
with ada.text_io; with ada.integer_text_io;
use ada.text_io; use ada.integer_text_io;
procedure declare_example2 is
type My_Array_Type is array(Natural range <>) of Integer;
size: natural;
begin
get(size);
declare
a: My_Array_Type(1 .. size);
begin
for i in a'range loop
get(a(i));
end loop;
for i in a'range loop
put(i);
end loop;
end;
end declare_example2;
Unconstrained Arrays as Parameters
- Array parameters must have a named type
- This won't compile:
procedure p(a: array(1..10) of integer) is
- Unconstrained arrays allow creation of procedures that work for any size array
- Example:
with ada.text_io; with ada.integer_text_io;
use ada.text_io; use ada.integer_text_io;
procedure declare_example2 is
type My_Array_Type is array(Natural range <>) of Integer;
-- Array a can be of any size
procedure putArray(a: My_Array_Type) is
begin
for i in a'range loop
put(i);
end loop;
end putArray;
a: My_Array_Type(1 .. 10);
begin
for i in a'range loop
get(a(i));
end loop;
putArray(a);
end declare_example2;