Whenever I get to array data structures or strings in my classes, it is always with some trepidation that I point out that array indices start at 0 not 1, as might seem more natural to a beginning programmer. If the class is the non-questioning sort, I just go on. But if some one asks, "Why?", and I think they can handle it, I take the opening. Most of these students have no real understanding of what a compiler or translator is or does. This is a chance to explain on a level they can understand, one of the jobs of a compiler, keeping track of addresses.
When you declare an array such as, int [] nums = new int[10];
nums is a reference to the address of the start of the array, sometimes known as the base address. It is assigned by the compile and is duly noted in the table of variables. Let's say for nums, that address is 2000. Sometime earlier we talked about the different number of bytes that each primative type needs for storing a value. For type int, it is 4 bytes in Java.
Here is the formula the compiler uses to determine the address of each element of the array nums:
address of element as index x = base address + size of each element in bytes * the index x.
The portion of the formula, size of each element in bytes * the index x, is known as the offset address. Now here is the cool part: since the index of the first element in the array is 0, the offset address works out to be 0 (0 times anything is still 0). So the base address just happens to be the base address of the array.
. Let's look at a differnet element. What is the address of element [7] (We are actually asking what is the address of the first byte of [7]). According to the formula: address of element[7] = base address (2000) + size of each element in bytes (4) * the index [7].
So the address of index [7] is 2000 + 4 * 7 = 2028.
Again the compiler keeps track of this. Of course, if you are programming in assembly language you will have to assume the responsibility of keeping track of addresses.
Now I admit I my explanation may not be totally correct in all cases but it serves as a good lesson on how math is used in programming even when the programmer doesn't do any.