By the end of this module, for simple programs with real
numbers, you will be able to:
Demonstrate ability to declare unidimensional
arrays and populate them, with integer and doubles.
Demonstrate knowledge of array limits, length.
Demonstrate simple operations like printing and copying.
Demonstrate mental execution and debugging of
array-based programs.
Identify new syntactic elements related to the above.
Note: As usual, for all modules, when you solve an exercise you will
either write a program or write an answer in the
appropriate module PDF. Some exercises will feature both a program
and an answer to be written in the PDF.
Thus, for this module, your non-program
answers will be in
module0.pdf,
whereas for other modules, use the appropriately named pdf.
0.0 Audio:
0.0 A group-of-items variable
First, recall our "box" analogy for a variable:
Suppose we declare and assign a value to an int
variable i
The variable is like a "box" that can hold one
single integer value at a time.
An array:
The analogy for an array: a "box" that
stores a group of related items arranged linearly:
The code that created the above:
Note: the following (which we could do with plain integers) is not allowed in Java:
Here is another way of accomplishing the assignment:
Note: Java uses square brackets for arrays, in three ways.
A declaration can declare an array variable
with empty square brackets (nothing in between).
int[] A = new int [5]
A number in between the brackets can indicate the size of
the array, as in "5" above.
int[] A = new int [5]
A number in between can access a particular
element of the array, as in each assignment above.
A[0] = 25;
Perhaps the most common way of declaring and using arrays looks like this:
Next, let's print the elements of the array:
0.1 Exercise:
Modify the above program (ArrayExample5.java)
to include a sixth element so that the elements
in order are: 36, 25, 16, 9, 4, 1. Print
the elements and the array length.
Let's look at a few details carefully:
First, the declaration:
It starts with the type of value in
each location of the array. Here: int.
Then the square brackets together.
Finally, the array variable name. Here it's A.
⇒ This is a name we chose.
Next, unlike int's or double's,
we need to explicitly create space for arrays:
Uses the reserved word new:
Recall: reserved words are words in the language that can't
be used as variable names, method names and the like.
This is followed by the type (here, int):
Which is followed by the desired size in square brackets:
Note: the value of the int in n is
used for the array size.
So, when do we use
versus
Use the latter for small arrays when all the array
contents are known ahead of time.
Use the former in all other cases.
The value used to access one of the array locations
is called an array index:
The first location always has index 0.
If the size is n, the last index is n-1.
An array index is always a non-negative integer between 0
and the size of the array minus 1.
Every array variable has an associated
length:
This length is an integer.
Note: the length is NOT the last index.
⇒ It is one more than the last index.
The length will be useful later.
In the example above, we (laboriously) wrote a println
for each array element.
⇒ We'd never do this in practice: instead, we'd use a
for-loop (see next section).
How to read aloud:
When you see
say to yourself
Oh, A is an
double array.
Its space of n elements has been created
with the new operator.
The values inside
of A aren't yet initialized.
B is another array,
an int array,
fully initialized to 5 values.
In the for-loop where i runs from 0 to n, "A's of i" is assigned
1 over "B's of i".
When you see
A[0] = 25;
say to yourself any of the following:
"A zero is assigned 25"
"A of zero is assigned 25"
"A's of zero is assigned 25" or
"A0 (sub zero) is assigned 25".
Let's now deliberately make a mistake to see what
happens: we'll use an index that's "out of bounds"
0.2 Exercise:
Edit, compile and execute the above program to see what happens.
0.1 Arrays and for-loops
Arrays go hand-in-hand with for-loops.
Note that the loop variable is used as the array index:
Here, the loop variable i takes values
0, 1, 2, 3, 4 in successive iterations.
For example, in the third iteration
i is 2.
Therefore, A[2] is given to
System.out.println.
The value of A[2] is 9 (third element).
The value printed is therefore 9.
We can use for-loops for filling in the elements of
an array, e.g.,
Here, we are cleverly using the for-loop variable i
for two different purposes:
One is to serially traverse the array (the second for-loop).
The other purpose is to use its value in an arithmetic expression,
whose value is eventually stored in the array (first for-loop).
0.3 Exercise:
In
module0.pdf,
trace through the first for loop iteration by iteration,
and draw the entire contents of the array at each step.
Note: for this and other tracing exercises,
you can save time by writing or drawing on paper and then
including a picture of the paper in the PDF (as long
as it's clear and legible).
0.4 Video:
0.5 Exercise:
In a file called MyArrayWithForLoop.java,
modify the above program
to include a sixth element, 36.
0.6 Exercise:
In a file called MyArrayWithForLoop2.java,
change the order of elements so that the order is:
36, 25, 16, 9, 4, 1. That is, the first element
in the array (A[0]) is 36, the second is
25 ... etc. Print the elements.
0.7 Exercise:
In MyArrayWithForLoop3.java,
change the printing for-loop
from MyArrayWithForLoop.java,
to print the elements in
reverse order (starting with A[5]).
0.8 Video:
0.2 Arrays of double's
Consider the following example:
Here, we have declared an array variable A
for an array of double values:
And created space for it (5 slots):
Then, we assigned values in a for-loop:
And used those values in printing:
0.9 Exercise:
In MyDoubleExample.java,
modify the above code to compute the sum (of the
first n terms) of the series
s = 1 + 1/22 + 1/32 + ... + 1/n2.
Then, compute the value 6s (6 times s) and find its square root
using Math.sqrt() (remember?)
Try this for different and possibly values
of n, finally submitting your program with n set to 25.
What do you think the square root of 6s
turns out to be for large n?
Recall how we computed fundamental math constants in Unit 0.
0.3 Default values
Consider this program:
0.10 Exercise:
What does the above program print?
Write it up in
DefaultExample.java,
What do you conclude
about the default values placed inside an array?
Is it the same for integer arrays?
0.11 Audio:
0.4 Assignment and copying with arrays
Consider the following program:
Here, we have created a second array B:
Each element is copied one by one:
0.12 Exercise:
In
module0.pdf,
draw out each array and trace through both for-loops
showing, step-by-step in pictures, how elements get
copied from one array to the other.
0.13 Video:
Now for something strange:
0.14 Exercise:
What does the program print? Write it up in
CopyExample2.java
and see.
Then, draw the box pictures for both arrays and see if that
explains the result.
About array copying and assignment:
Yes, it's a little strange.
When array variables are used in direct assignment, as in
The variable B gets associated with the
same array space as A's.
We say that "A and B
point to the same array space".
This is why B[0] and A[0] are
the same "box".
This is true for the other slots.
For example, B[1] and A[1] are
the same "box" too.
0.15 Exercise:
Does it work the other way around?
Write this up in
MyCopyExample2.java.
What gets printed out?
0.16 Exercise:
Consider this program:
public class CopyExample3 {
public static void main (String[] argv)
{
int n = 5;
double[] A = new double [n];
for (int i=0; i<n; i++) {
A[i] = 1.0 / ((i+1)*(i+1));
}
// What is the value of A[0] here?
System.out.println (A[0]);
// Something strange:
System.out.println (A);
double[] B = new double [n];
A = B;
// What is it here?
System.out.println (A[0]);
// Weirdness once again:
System.out.println (A);
System.out.println (B);
}
}
Write this up in CopyExample3.java.
What gets printed out? Explain the different values of
A[0]
(in
module0.pdf).
0.17 Video:
0.5 Explaining the strangeness of arrays: a peek under the hood
Let's focus on three aspects of arrays that seem to beg
explanation:
Why do array indices start from 0?
⇒
That is, why start with A[0]
and not
A[1]?
How come when one array variable is assigned to another,
both seem to affect the same contents?
// An array A:
int[] A = {25, 36, 49, 64};
// An array B:
int[] B;
// What appears to be a copy:
B = A;
// Prints 25 as expected:
System.out.println (B[0]);
B[3] = 16;
System.out.println (A[3]);
// Prints 16 (unexpectedly), implying that A[3] has been changed to 16
Why exactly, when we set the first entry of
B
to
0
did the first entry of
A
also get set to
0?
What are those strange things printed out when we have
// Something strange:
System.out.println (A);
To understand why, we're going dig a little deeper:
Remember the "boxes" idea?
Variables like
int i = 5;
have a box in memory. Here, the value
5
gets into the box.
We'll now understand these "boxes" in a little more detail.
Think of a computer's memory as a long list of boxes,
where each box has a number:
A box's number is like the number of a apartment mailbox.
The numbering starts from 0 and goes up to the size of
the memory (which can be quite large).
Every variable lives somewhere in memory.
Let's use this example to further explain:
// A simple 4-element array of integers:
int[] A = {25, 36, 49, 64};
// Declare B, assign it A
int[] B = A;
// Use a for-loop to print B
for (int i=0; i<4; i++) {
System.out.println (B[i]);
}
// Modify the 4-th element of B:
B[3] = 81;
// Print the 4-th element of A:
System.out.println (A[3]); // Prints 81
First, let's examine this conceptual picture of memory:
Examine the box for
i:
It so happens that this particular time
(the Java system determines this) that
the box for
i:
is at location 8673.
This location can change with every new execution of the
program but stays fixed during an execution.
When the for-loop executes, this is where the values
0,1,2,3
will live, as the iterations proceed.
Now, the box for
A
is a little different:
Inside the box is an address of another box: 1032.
If we look at box #1032, we see that that is where the
first element of the array
25
happens to reside.
This is no coincidence. It is by design.
Next, notice that all the array elements of
A
are contiguous, one after another.
This too is by design.
To access array elements, what really happens under the
hood is this:
The first element,
A[0],
is at 1032 + 0.
The second element,
A[1],
is at 1032 + 1.
The third element,
A[2],
is at 1032 + 2.
And so on.
We don't do this in our program, but underneath, that
is what Java is doing when the program runs.
In fact, in a for-loop, the i-th element,
A[i],
would be found at 1032 + i.
So, the computer "goes" to location 1032 + i
to fetch its contents as
A[i].
Next, let's consider what happens when
int[] A = {25, 36, 49, 64};
int[] B;
B = A;
System.out.println (B[0]);
gets executed.
The state of memory is now:
Here, we say "B points to the same place A is pointing to".
That place is the start of the actual array contents (1032
in this case).
Thus, when we execute the println
int[] A = {25, 36, 49, 64};
int[] B;
B = A;
System.out.println (B[0]);
B
has the value 1032 and so
B[0]
refers to the first element, which means 25 gets printed out.
Next, consider what happens next:
int[] A = {25, 36, 49, 64};
int[] B;
B = A;
System.out.println (B[0]);
B[3] = 16;
System.out.println (A[3]);
The assignment
B[3] = 16
changes the 4-element of the array "pointed to" by
B.
So, the picture of memory now becomes:
Thus, the value in
A[3]
is now 16.
Lastly, what was that strange output we saw when we executed
// Something strange:
System.out.println (A);
What we see is the address in
A
being printed out.
If the address were actually 1032 (as in our picture)
that is what would get printed out.
However, Java's address list is quite large and most
addresses have many digits (not four as in 1032).
In fact, it's so large that the decimal system proves
inconvenient, which is why hexadecimal numbers (base 16)
are used. These have the letters a,b,c,d,e,f in them.
We don't need to understand how "hexadecimal". Just think
of those as addresses, like a mailbox address.
0.6 More examples
Example 1: let's write a program to "rotate" an array:
Thus, we want to shift each element into the next position rightwards.
The last element gets into the first position.
First, we'll use the help of an additional array to
make this happen:
We first copied elements A[0],...,A[n-2] into
locations ("boxes") B[1], ..., B[n-1].
Then, we copied A[n-1] into B[0].
The array B is in the desired form.
Lastly, we copied all of B into A
so that A has the desired rotation.
0.18 Video:
0.19 Exercise:
In
module0.pdf,
draw out each array in each step, showing the
contents.
It is possible to do without an additional array:
0.20 Exercise:
In
module0.pdf,
trace through the above example (RotateExample2.java)
by hand to see how it works. Then, also trace through (in same PDF)
the version below and explain why it does not work:
Next, in the second example, we'll write code to reverse an array:
Here's a version that uses an additional
array:
0.21 Exercise:
Trace through the program above
(in module0.pdf).
0.22 Exercise:
Write code in
MyReverseExample.java
to achieve reversal
in the same array A,
without using an extra array like
B.
0.23 Audio:
Example 3: adding two arrays
Here, we have added two arrays element-by-element.
The resulting values are put into a third array
(C).
0.24 Exercise:
Trace through the program above
(in module0.pdf).
0.25 Exercise:
Write a different version
(in AdditionExample2.java) that
takes an array A and computes
the following sum of two arrays, element by element, as in the
above example.
However, in this case, you are to compute the sum (element-by-element)
of the array A and its reversal,
putting the
result into array B.
Print the contents of array B,
and to test your program use the same contents for
array A as above.
Do this without using a third array.
0.26 Exercise:
In module0.pdf,
trace through the program below by hand.
What does it print?
0.27 Exercise:
In module0.pdf,
trace through the program below by hand.
What does it print?
0.28 Exercise:
In module0.pdf,
trace through the program below by hand.
What does it print? Look up the definition of
factorial somewhere and relate that to
the computation above.
0.29 Video:
Note: in the exercise above, we learned a few new
things about using arrays:
Sometimes, we create one additional slot so that
we can use the index A[n] when convenient.
A for-loop can have other variables that change
with the loop besides the loop variable.
0.7 Reading and writing
Let's look at an example and how to read the code:
First, look for the array declaration and identify the
type (e.g, int or double etc):
Say to yourself, "A is an array that holds
double's".
"B is an array that holds
int's".
Then, look to see how much space is created:
Say to yourself, "A's size is 5, created
using the new operator".
"A's elements are all initially 0".
"B's size is 5, directly initialized to
particular values".
Now, check that, when variables are used to access
array components (slots), the bounds are right:
Writing:
Writing the declaration:
No spaces between either the type (double),
nor between the brackets.
A single space between the right bracket the array variable
name.
Creating space:
A space on either side of the assignment operator, =.
A space on either side of the new reserved word.
The space after the double is optional. (Here, we have
a space.)
No spaces for the size and brackets.
Prefer the use of the new operator except
for small-ish arrays whose initial contents are known and fixed.
No spaces when using the values in an array:
Using the array's built-in length. Consider this variation:
We could either n or the array's length A.length.
So, which one should we use?
Generally, when the limit is a mathematically meaningful
variable like n above, you can use n.
Otherwise, use the array's length.
Sometimes, using an array's length variable can make
a program needlessly verbose.
For example, here's the array-reversal example using
the length variable:
Variable names:
Here is the first length example, re-written with
different variable names:
For a program this short, it is probably a bit verbose.
Notice: we used different names for the loop variables
in the two for-loops.
0.8 When things go wrong
Which of the following have errors (syntax or bugs)
and what are they? Can you tell just by reading?
Don't pay attention to the purpose - just whether
the program will compile or run.
0.30 Exercise:
0.31 Exercise:
0.32 Exercise:
0.33 Exercise:
The following program has multiple errors. See if you
can spot them by reading. Then in
ErrorExample4.java
fix the errors by editing the program. The array
A
needs to be an array of
double's.