A slight tangent, but something that surprised me: The [] operator literally is just syntactic sugar for pointer dereferencing and addition, so that the following equivalence holds:
a[b] == *(a + b);
The surprising consequence of this is that the following is legal:
int foo[] = { 1, 2, 3 };
int bar = 2[foo]; /* yes, this evaluates to 3 */
because
*(2 + foo)
is legal, and + is commutative. This works for both pointers and arrays. I haven't worked out a practical use, though I suspect the C++ metaprogramming crowd might have. Obviously the equivalence only holds on the native types in C++ as [], + and * can each be separately overloaded.
The only problem is that in C++, overloading operator[] has to be a non-static member function. x[y] is treated as x.operator[](y) if x is of class type. So x[y] may not be the same as y[x] if they are class types. So maybe that has some useful property, but it isn't really the same.
First off, I think is is an interesting article highlighting the difference between pointer arithmetic and array access. As far as the title goes, I think the answer should be a quick and obvious no. Pointers are variables that contain a particular memory address. Arrays are CONSECUTIVE pieces of memory where the variable name holds the address of the first piece of allocated memory. Conceptually, this is very different and the article does quite a nice job explaining the low level details of why you cannot gloss over this difference. The bit about arrays being converted to pointers in functions is left on my to read pile for now...
Arrays and pointers are not the same type. Pointers are used to access array elements, however the variable itself is not a pointer type. It's an array of some other type (which can also be an array). In addition to automatic memory allocation that happens with an array, this matters whenever compile-time type-checking happens.
So I guess it depends on what you mean by "equivalent."
Also... Arrays have block scope. So if you have a function that declares an array, operates on it, then returns a pointer to that array, it's undefined behaviour.
This was very confusing to me when I learned C because it's one of those undefined behaviours that appears to work properly in trivial programs (at least with the compiler I was using).
EDIT: ugh, this is not working right. I can't figure out how to get the asterisks to not italicize ( I was trying to show an example).
Variables have block scope, but storage duration need not. If you return a pointer to a block of memory allocated within a function, that is not undefined behaviour. If you return a pointer an array declared within the function that is (if you return a pointer to a static array declared within a function that is not). That's the contrast I was trying to point out.
struct {
char somechar;
char somearray[7];
} foo = {'E', "xample"};
printf("%c\n", foo.somearray[-1]); // prints 'E'
// (depending on your compiler and the
// struct-packing directions you gave it)
(depending on your compiler and the directions you gave it)
I don't think I was trust this piece of code in a commercial application. There is too much variation which would make it unreliable across platforms and compilers.
The negative array index here is a bit perverse, granted. But the general idea of using structs (with ideally controlled, but hopefully at least well-known, packing) is surprisingly common, in my experience. I've seen it used for defining binary file and wire formats (which is perhaps somewhat dodgy but there you have it) and, perhaps more appropriately, for EEPROM layouts and the like in embedded systems.
> Here’s a quote from Expert C Programming:
>
> There is one difference between an array name and a
> pointer that must be kept in mind. A pointer is a
> variable, so pa=a and pa++ are legal. But an array
> name is not a variable; constructions like a=pa and
> a++ are illegal.