



                                                       Chapter 10
                                                           ARRAYS


OUR FIRST ARRAY
_________________________________________________________________

An array is a group of two or more elements that ================
are all of the same type.  In Ada, as in most       ARRAY1.ADA
modern computer languages, arrays can be made of ================
many different kinds of data, but all elements
of an array must be of the same type.  The best
way to see this is to inspect the program named ARRAY1.ADA which
contains a few examples of arrays.



HOW DO WE DECLARE A SUBSCRIPT?
_________________________________________________________________

For simplicity, we will start with line 11 where we have a
declaration of the array named Dummy1.  This line says that the
variable named Dummy1 will have 7 elements numbered from 1 through
7, and each element will have the ability to store one BOOLEAN
variable.  We will see shortly that the individual elements will
be referred to by the variable name followed by a subscript in
parentheses, or Dummy1(1), Dummy1(2),... to Dummy1(7).  Keep in
mind that each is a single BOOLEAN variable.

To define an array, we use the reserved words array and of with the
appropriate modifiers as illustrated in this example.  We define
a range which the array will cover, the type of the range variable,
which must be composed of discrete type limits, and the type of
each element of the array.  Remember that a discrete type is any
type of the integer class including enumerated types.  We will have
an example program with an enumerated array index in part 2 of this
tutorial.



LET'S LOOK AT ANOTHER ARRAY DECLARATION
_________________________________________________________________

In line 12, we have Dummy2 defined as an array of BOOLEAN type
variables that covers the range of Dummy2(-21) through Dummy2(10),
since N has the value of 10.  Line 13 illustrates declaring the
array Dummy3 as an array of BOOLEAN variables from Dummy3(-21)
through Dummy3(10), but this time the subscript type is not
explicitly stated, only implied by the values of the subscript
limits.  Actually, the subscript type was not needed in the first
two either, since they were implied.  The type INTEGER is used so
often for an array subscript that the type INTEGER has been defined

                                                        Page 10-1

                                              Chapter 10 - Arrays

as the default if none is given.  This is done only to make it a
little simpler to use arrays.

So far in this program, we have defined about 70 variables that
have no initial values because we have not assigned them any.  We
will see how to initialize an array later, but first we should
learn how to use them.



HOW DO WE DEFINE AN ARRAY TYPE?
_________________________________________________________________

Line 15 gives the general method of declaring an array type.  It
uses the reserved word type followed by the type name, the reserved
word is, then the definition of the type.  The definition is
composed of the range, followed by the reserved word of and the
element type.  We now have a type name which can be used to define
any number of array variables, and each will be made up of integer
variables.  Each will also have 5 elements and will cover the range
of 1 through 5.  Thus line 17 defines an array of five elements
named Total, the elements of which will be named Total(1),
Total(2), ... Total(5).  Each of these elements can be used to
store one data point of type INTEGER.

Line 25 of the program illustrates how we can assign a value of 12
to one of the elements of First, which is another array of type
MY_ARRAY and therefore composed of 5 elements.  The second element
is assigned the value of 16, and the third is assigned a value
found by subtracting the first element from the second, resulting
in a value of 4.  This illustrates the use of the elements once
they are assigned values.  The fourth and fifth elements are also
assigned nonsense data, illustrating some mathematical operations.
The assignment in line 28 will be explained in the next paragraph.
If you remember that each element is an INTEGER type variable, you
can use them just like any other INTEGER type variable, except that
you must add the subscript to indicate which element you are
interested in using at each point in the program.



RENAMING AN ARRAY ELEMENT
_________________________________________________________________

Line 22 is an illustration of renaming a single element of the
array.  Once again, this simply gives us a synonym which we can use
to refer to the variable, it does not declare another variable.
It should be pointed out that it is not permitted to rename a type
but you can achieve the same effect by declaring a subtype with the
same range as the type which you wish to have another name for.





                                                        Page 10-2

                                              Chapter 10 - Arrays

WHAT IS A RANGE_ERROR?
_________________________________________________________________

Any attempt to use a subscript which is outside of the assigned
range will result in the system raising the exception Range_Error,
and will be handled as a fatal error, terminating operation of the
program unless you handle the exception yourself.  We will study
exceptions in part 2 of this tutorial.

The subscript can be a variable itself, provided it is of the
correct type, as is illustrated in line 32, where all five elements
of the array named Second are assigned nonsense data for
illustration.  The subscript can also be calculated, with any
arbitrary level of complexity, provided of course that it results
in an INTEGER type result and is within the range of the declared
subscript.



ARRAY ASSIGNMENT
_________________________________________________________________

The assignment in line 35 is legal, provided the two arrays are of
the same type, resulting in all 5 values of the array named First
being assigned to the five elements of the array named Total.  Line
36 illustrates that arrays can even be compared for equality or
inequality, and they are considered equal if each element of Total
is equal to the corresponding element of First.  If there is any
inequality, the result is FALSE.

Lines 41 through 48 illustrate a few more of the permissible
operations on arrays.  You should have no trouble studying them on
your own.



WHAT IS AN ANONYMOUS TYPE?
_________________________________________________________________

In line 15, we defined a type and gave it a name which we could
then use at will throughout the remainder of the program.  Any
array of this type is said to be of type MY_ARRAY, because it has
a name assigned to it.  The array declared in line 20 does not have
a name associated with it, so it is referred to as an anonymous
type.  An array is the only place in Ada where it is possible to
have an anonymous type, and its use should be discouraged for
reasons to be seen shortly.

The array assignment in line 35 was only possible because the two
arrays were of the same exact type, and in order to be of the same
type, they must be declared with the same type name.  The array
named Funny has the identical structure as the array First, but it
was not declared with the same type name, and it is therefore of
a different type and cannot be used in an array assignment

                                                        Page 10-3

                                              Chapter 10 - Arrays

statement.  Since the array Funny is of an anonymous type, it is
impossible to define another array with the same type, so it is
impossible to use this array in an assignment statement with any
other array.

Line 21 declares the arrays X and Y in the same statement, and it
would seem that they should have assignment compatibility, but
according to the definition of Ada, the two arrays are of different
types because naming both variable names in one statement is merely
a shorthand method for naming them in two separate lines.  The two
arrays are therefore each of a separate anonymous type.  This is
a fine point, but should be clearly understood.

Two arrays are assignment compatible only if they are declared with
the same type name.  Compile and run this program and compare the
output with the output you expect.



WHAT IS A SLICE OF AN ARRAY?
_________________________________________________________________

The program named SLICE.ADA contains several      ===============
examples of the use of the slice in Ada, which       SLICE.ADA
is a portion of an array.  You may wish to        ===============
assign part of an array to part of another array
in a single statement.  This can be done with a
slice.

We begin by declaring an array type, MY_ARRAY, which is then used
to declare two arrays, First and Second.  Finally we declare a
third array named Funny, which is of an anonymous type as defined
in the last example program.  This example program will illustrate
the difficulty of working with an array of anonymous type, but we
will start by working with the named arrays.



WHAT IS A SLICE?
_________________________________________________________________

In the executable part of the program, we assign nonsense values
to the arrays named Funny and First, so we will have some data to
work with.  Then in line 25 we tell the system to take elements 3
through 7 of the array named First and assign them to elements 1
through 5 of the array named Second.  The term on each side of the
assignment operator is a slice, a portion of an array.  In order
to do the slice assignment as illustrated, both arrays must be of
the same type and both slices must have the same number of
elements.  Of course, all slice limits must be within the declared
range limits of the subscripts for the type in use.  Line 26
illustrates copying 4 elements from First to Second, and line 27
illustrates copying 6 elements.


                                                        Page 10-4

                                              Chapter 10 - Arrays

In line 28, eight elements are copied from an array to itself in
such a manner that the destination and origin portions of the array
overlap.  Ada is defined such that all of the values are copied in
true fashion rather than recopying some earlier copied values again
as the copying of values continues.  This is because the entire
right hand expression is evaluated before the assignment is made
to the left side variable.  Note that the slice can only be used
with a singly dimensioned array.



BACK TO THE ANONYMOUS TYPE VARIABLE
_________________________________________________________________

We said that the variable named Funny is an anonymous type and that
it would cause some difficulties, so let's see what the problems
are.  In order to assign all or part of an array to another type
of array, we must use a type transformation or get a compile error.
Line 30 illustrates how to use a type transformation, as we have
seen before. However, we can only do a type transformation based
on the entire array, not a portion of it, so we can only transform
the type from anonymous to a full sized array of the target type,
MY_ARRAY.  Therefore we can only copy a slice from the anonymous
type variable into the full array of the target.  There is no way
to transform the type from MY_ARRAY to the anonymous type, since
the anonymous type doesn't have a name, so a slice cannot be used
to assign to the array variable named Funny.  Line 31 illustrates
another slice assignment to the complete array named First.

The entire array named First is displayed for your observation.
Compile and run this program and examine the output.



A MULTI DIMENSIONAL ARRAY
_________________________________________________________________

Examine the program named MULTARY1.ADA for our   ================
first example of a multidimensional array.  We     MULTARY1.ADA
begin by declaring a type named MATRIX which is  ================
composed of an array of an array with a total of
12 elements.  Each element of the array is
referred to by two subscripts following the variable name in
parentheses as illustrated in the executable part of the program.
Lines 21 through 26 contain a nested loop to fill the variable
named Square_Board with a multiplication table, and to fill
Chess_Board with all zeros.  Note that the variable named
Chess_Board is of an anonymous type because there is no type name
associated with it.

The entire array named Square_Board is assigned to the array
Checker_Board which is legal because they are of the same type,
which means they were defined with the same type name.  Line 30 is
used to assign a value of 2 to one element of the Checker_Board,

                                                        Page 10-5

                                              Chapter 10 - Arrays

and that value is used in line 31, which states,
"Checker_Board(2,4) := 17;", because line 30 assigned the value of
2 to Checker_Board(2,3).

It should be clear to you, based on the discussion of the last
program, that even though Chess_Board has the same structure as
Square_Board, they are not type compatible and are not assignment
compatible.  The individual elements are assignment compatible
however.

The array named Checker_Board is displayed which you can observe
when you compile and run this program.



WE NEED SOME FLEXIBILITY
_________________________________________________________________

This program used fixed values for all of the    ================
range and loop definitions, which allows very      MULTARY2.ADA
little flexibility, and is therefore considered  ================
to be poor programming practice.  Of course, it
was done for clarity since this was your first
look at a multidimensional array.  The next program, named
MULTARY2.ADA is much more flexible and illustrates some of the
slightly more advanced techniques which can be used with Ada.

This program is identical to the last except that there are two
constants defined in the declaration part which are then used to
define the limits of the arrays and the loops.  If you needed to
make the program cover a larger range, it would be trivial to
modify the constants and recompile the program.  Compile and run
this program and you will see that it does exactly the same thing
as the last one.



WE NEED MORE FLEXIBILITY
_________________________________________________________________

Examine the program named MULTARY3.ADA and you   ================
will find that it is identical to the last two     MULTARY3.ADA
except in the way we define the loop limits.     ================
Recall the information we covered on attributes
in an earlier lesson and the additions to this
program will be simple for you to understand.  In line 24 we use
the attribute LAST to define the upper limit of the outer loop and
add the digit "1" in parentheses to tell the system that we are
interested in the first subscript of the array named Square_Board.
Line 25 uses a "2" to indicate the LAST value of the second
subscript of Square_Board.  If no subscript indication is given,
the system will default to "1", but it is much clearer for the
reader to indicate the "1" in parentheses. It may seem to you to
be a lot of trouble to define the limits this way, but when we get

                                                        Page 10-6

                                              Chapter 10 - Arrays

to the point where we are writing generalized procedures we will
need the flexibility given here.  Generic procedures are a long way
off too, but these techniques will be absolutely essential when we
study them.

Lines 37 and 38 also use attributes for the two loop ranges, but
they use the RANGE attribute with the number of the desired
subscript in parentheses once again.
When using a singly subscripted array, it is legal to use a "1" in
parentheses also, but if none is given, the system will default to
one.  You should explicitly include the number in a
multidimensional array and omit it for a singly dimensioned array
as a matter of programming clarity.



WHAT IS AN AGGREGATE?
_________________________________________________________________

An aggregate is a grouping of numeric literals, although
enumeration values could also be included, that is used to
initialize an array in the present case.  The literals can be
grouped in the order in which they are used, and this is referred
to as a positional aggregate.  The literals can also be in a named
aggregate, in which the use for each value is defined by using the
name of the location to which it should be assigned.  The
definition of mixed notation will be deferred until later since it
is not permitted to be used for array initialization anyway.



HOW DO WE INITIALIZE ARRAYS?
_________________________________________________________________

Examine the program named ARRYINIT.ADA for some  ================
examples of array initialization.  Seven arrays    ARRYINIT.ADA
are declared and the method of aggregate         ================
notation, both positional and named, are
illustrated.  The variable Total is initialized
using the positional notation and the variable First is initialized
by use of the named notation.  Mixed notation is not allowed for
array initialization.  The array named Another in line 16 contains
a new construct using the reserved word others in conjunction with
the named aggregate notation.  If included, it must be the last
entry in the aggregate.  The values of Another(1), Another(3), and
Another(4) will be initialized to the value of 3.  The array named
One_More in line 18 illustrates initialization of a range of
variables to the value 13, and two variables to the value 27.  Note
that the others case can be included here but must be last and
alone.  The other singly dimensioned arrays should pose no problem
for you but a few comments are in order concerning the multi
dimensional arrays.



                                                        Page 10-7

                                              Chapter 10 - Arrays

Even though you are not permitted to use mixed aggregate notation
for an array, the rule is applied at only one level so you can use
different methods for each level.  The variable Square_Board uses
all positional notation, but Checker_Board uses a named aggregate
for the first subscript and positional for the second.  Chess_Board
mixes things up a little more by using a named aggregate for the
first subscript and both methods for the second subscript even
though it is consistent within each subgroup and is therefore
obeying the rules.



MORE ARRAY EXAMPLES LATER
_________________________________________________________________

There is more to be said about arrays, but it will have to wait
until we cover a few more topics.  This is meant to get you started
using arrays, but in a later chapter we will cover additional array
topics.



PROGRAMMING EXERCISES
_________________________________________________________________

1.   Modify ARRAY1.ADA in such a way that the variables X and Y are
     assignment compatible.

2.   Write a program with two arrays of size 3 by 5 each and
     initialize each to a suitable set of integer values.  Multiply
     these, element by element, and store the values in a third
     array.  Finally, display the results in a clear format on the
     monitor.




















                                                        Page 10-8