> how does it know to treat it as an array of nine chars
"It" doesn't. We know.
> and how does say if move == '7' which becomes [0][6] according to the syntax,
> then know to point to 1,2 in your diagram?
Ok. Let us start from first principles.
If we have
char a[3] ;
a
is an array containing three elements of type char.
If
T
is some type, and we have
T b[3] ;
b
is an array containing three elements of type
T
.
The elements of an array are allocated contiguously in memory; one after the other, leaving no gaps in between. So
T b[3]
looks as in the first diagram above, where each element is of type
T
.
When we say
b[0]
we are referring to the element at position
0, the element that is right at the beginning of the array. (Actually the
[] is an operation on a pointer, but we will leave that nicety aside for the moment.)
When we say
b[1]
we are referring to the element at position
1, the element that is immediately after the element at position
0.
In general, when we say
b[n]
, we are referring to the element at position
n, the element that is
n elements away from the element right at the beginning of the array. Since we specified
b, the compiler 'knows' which array we are talking about, and since we specified
n, the compiler 'knows' which element of that array we are talking about. Using this information, it figures out where the element
b[n]
would be and generates the code to access that element. While doing this, it places implicit trust in the programmer; it takes for granted that there must an element at position
n; that there are at least
n more elements after the the first one at position
0.
Now it is easy to see what would happen if we try to modify
b[7]
. The compiler assumes that we know what we are doing; we have asked it to access an element which is seven elements away from the begining of
b and would generate the code for doing precisely that. However, there are only three elements in the array, at positions
0,
1 and
2; there are no elements after that; an element at position
7 just does not exist. And when we run our program, unpleseant things happen. The C++ language refuses to say anything about how bad it could possibly get; in this situation, C++ permits the implementation to get as nasty as it pleases. (In jargon: this results in 'undefined behaviour'.)
Now let us replace this hypothetical
T
with an actual type:
1 2 3
|
typedef char T[3] ; // the type T is 'array of three chars'
T b[3] ; // b is an array of three elements of type T
char arr[3][3] ; // arr is an array of three elements of type T
|
'b' and
'arr' are of the same type; they are laid out as in the second diagram above.
b[0]
or
arr[0]
is the element at position
0, an array of chars, right at the beginning.
arr:
1 2 3 4 5
|
__________________________________________________________________________________
| | | |
| 0 | 1 | 2 |
| | | |
__________________________________________________________________________________
|
1 2 3 4 5
|
__________________________________________________________________________________
| | | | | | | | | |
| 0,0 | 0,1 | 0,2 | 1,0` | 1,1 | 1,2 | 2,0 | 2,1 | 2,2 |
| | | | | | | | | |
__________________________________________________________________________________
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
arr[0]
____________________________
| | | |
| 0 | 1 | 2 |
| | | |
____________________________
arr[1]
____________________________
| | | |
| 0 | 1 | 2 |
| | | |
____________________________
arr[2]
____________________________
| | | |
| 0 | 1 | 2 |
| | | |
____________________________
|
arr[0][6]
accesses an element six positions away from
arr[0][0]
1 2 3 4 5
|
__________________________________________________________________________________
| | | | | | | | | |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| | | | | | | | | |
__________________________________________________________________________________
|
whilch is the same element as
arr[2][0]