
Are pointers and arrays equivalent in C? - r11t
http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/
======
pmjordan
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.

~~~
JeremyStein
No practical use?! Why, it's practically a requirement for IOCCC entries. :)

~~~
mark_h
In fact, I recently only realised this myself this courtesy of this article (a
tutorial on writing obfuscated C :)):

<http://www.dreamincode.net/forums/index.php?showtopic=38102>

It makes perfect sense when you consider the semantics of [], but I never
would have thought to try it myself!

------
keefe
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...

------
dimitar
The answer to the same question here:
<http://c-faq.com/aryptr/aryptrequiv.html>

``pointer arithmetic and array indexing [that] are equivalent in C, pointers
and arrays are different.''

------
anamax
No.

Array names are immutable. Pointer values may be mutable.

However, let's ignore that and consider "int a[10]; int * const p(a);"

sizeof(a) is the size of the array named a or 4 * sizeof(int). sizeof(p) is
the size of the pointer named p.

~~~
matthavener
sizeof(array) works in a block, but as a function parameter, it'll return
sizeof(void*).

i.e. void f(int a[4]) { printf("%d", sizeof(a)); } int main() { int b[4];
f(b); } ... yields "4" (on my 32-bit machine)

------
Goladus
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."

------
parse_tree
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).

~~~
tesseract
If you have a function that declares _anything_ and returns a pointer to it,
it's undefined behavior. Because _variables_ have block scope.

~~~
parse_tree
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.

------
DarkShikari
Another difference is that:

    
    
        array[-1]
    

is not valid, while

    
    
        pointer[-1]
    

can be valid, such as if it points to the middle of a data set.

~~~
tesseract

        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)

~~~
NathanKP
_(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.

~~~
tesseract
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.

------
zouhair
Some of you maybe interested in this course
<http://www.reddit.com/r/carlhprogramming>

~~~
zeynel1
Thanks for the link, it's a great read.

------
huhtenberg

      > 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.
    

That's deep.

