A: 

In C arrays "decay" to pointers to their first element in certain contexts. Passing an array to a function is one of these cases.

sepp2k
+7  A: 

Any array argument to a function will decay to a pointer to the first element of the array.

The C Book has an excellent explanation of this:

Another case is when an array name is the operand of the & address-of operator. Here, it is converted into the address of the whole array. What's the difference? Even if you think that addresses would be in some way ‘the same’, the critical difference is that they have different types. For an array of n elements of type T, then the address of the first element has type ‘pointer to T’; the address of the whole array has type ‘pointer to array of n elements of type T’; clearly very different

detly
A: 

Because local arrays are treated as a special case (they decay to pointers).

In your case &a is translated to a.

If you try with an int pointer, e.g.,

int c = 3;    
int* p = &c;

you should get different values.

Mau
A: 

An array "decays" into a pointer to it's elements in some situations. Passing it as an argument to a function is one of those. Thus in

void func(int * pi, size_t nints);
int a[3] = {0, 1, 2};
func(a, 3);

the pointer to a is passed to func. This is what happens in your code as well. This also happens when you assign it to a pointer:

int * pi = a;
assert(*pi == 0); assert(*(pi + 1) == 1); assert(*(pi + 2) == 2);

The asserts here would also work if you replace pi with a.

Tim Schaeffer