ptr = array2; arr = array2; array =
array2;/FAILS/
} } }
The statement array = array2; will cause a compiletime error along the lines of "cannot change
the value of an array name". But it is valid to write arr = array2; because arr, though declared
as an array, is actually a pointer.
Indexing a Slice
An entire array is passed to a function by giving it a pointer to the zeroth element, but you can give it a
pointer to any element, and pass in just the last part of the array. Some people (primarily Fortran
programmers) have extended this technique the other way. By passing in an address that is one before
the start of the array (a[-1]), you can effectively give the array an index range of 1 to N, instead of 0
to N - 1.
If, like many Fortran programmers, you are used to programming algorithms where all the arrays have
bounds 1 to N, this is very attractive to you. Unhappily, this trick goes completely outside the
Standard (Section 6.3.6, "Additive Operators," is where it is prohibited), and indeed is specifically
labelled as causing undefined behavior, so don't tell anyone you heard it from me.
It is very simple to achieve the effect that Fortran programmers want: just declare all your arrays one
element larger than needed so that the index ranges from 0 to N. Then only use elements 1 to N. No
muss, no fuss. It's that easy.
Arrays and Pointers Interchangeability Summary
Caution: don't read this unless you've read and understood the preceding chapter, or it may cause
permanent brain-fade.
- An array access a[i] is always "rewritten" or interpreted by the compiler as a pointer
access *(a+i); - Pointers are always just pointers; they are never rewritten to arrays. You can apply a
subscript to a pointer; you typically do this when the pointer is a function argument,
and you know that you will be passing an array in. - An array declaration in the specific context (only) of a function parameter can equally
be written as a pointer. An array that is a function argument (i.e., in a call to the
function) is always changed, by the compiler, to a pointer to the start of the array. - Therefore, you have the choice for defining a function parameter which is an array,
either as an array or as a pointer. Whichever way you define it, you actually get a
pointer inside the function. - In all other cases, definitions should match declarations. If you defined it as an array,
your extern declaration should be an array. And likewise for a pointer.
C Has Multidimensional Arrays...
Some people claim that C doesn't have multidimensional arrays. They're wrong. Section 6.5.4.2 of the
ANSI standard and its footnote number 69 says: