A and & a are different for an array passed as a function parameter in C

Why are the values ​​of a and & a different for the array passed as a parameter to the function? b and & b are not different for an array defined inside the function body. Code follows:

void foo(int a[2]) { int b[2]; printf("%p %p\n", a, &a); printf("%p %p\n", b, &b); } int main() { int a[2]; foo(a); return 0; } 

EDIT:
So, after the discussion, I understand that the following happens:

In main() :

 int a[2]; /* define an array. */ foo(a); /* 'a' decays into a pointer to a[0] of type (int*). */ /* since C is pass-by-value, this pointer is replicated and */ /* a local copy of it is stored on the stack for use by foo(). */ 

In foo() :

 printf("%p %p\n", a, &a); /* 'a' is the value of the pointer that has been replicated, */ /* and it points to 'a[0]' in main() */ /* '&a' is the address of the replicated pointer on the stack. */ /* since the stack grows from higher to lower addresses, */ /* the value of '&a' is always lower than a. */ 
+7
source share
3 answers

Basically, when you type void foo( int a[2] ) , you write in a funny way void foo( int *a ) .

I would have to look for a specific quote from the standard, but when the function signatures are analyzed, the argument of the type array of N elements of type T is converted to a pointer to T. When you later type foo(a) , a decays to a pointer to the address of the first element that is being copied. Inside foo you are comparing the value of the pointer to the first element of the array a in main with the address of the pointer a in foo .

On the other hand, within the same function, when the array is located within region b inside foo , the address of the array ( &b ) and the address of the first element of the array (which can be obtained by forcing decay by typing b ) are the same address.

Two simple pieces of information for the future:

  • arrays in function signatures are interpreted as pointers: avoid syntax and use pointer syntax, you will get fewer surprises
  • which indicate the decay of the array into a pointer to the first element in most contexts

Example:

 void foo( int a[2] ); // void foo( int *a ); int main() { int x[2]; foo( x ); // foo( &x[0] ); -- inside foo, a is a copy of &x[0] printf( "%d\n%d\n", (int)&a, (int)a ); // &a[0] which is the same address as &a // (different type though) } 
+10
source

An array is not a pointer. It evaluates a pointer in almost all contexts, but one of the notable exceptions is the & operator.

So, if you call a function with an array as a parameter

 f(a); 

the a evaluates the address of the first element &(a[0]) , which is passed to the function.

If you use &a , the address of the array as a whole is taken. It has the same meaning as &(a[0]) , but the type is different. &(a[0]) is of type "pointer to base type", while &a is of type "pointer to array of base type".

Inside the &a function is something else. Here a is a "pointer to basetype", therefore &a is of type "pointer to a pointer to a base type", and the address you see is the address of the pointer on the stack, not your original array.

+3
source

When you pass a parameter by reference to a function, you technically push the address of the element on the stack of function calls. When you use & with a function parameter, you get the address of this value. I will try to illustrate this (all addresses are arbitrary, just for demonstration):

 int main() { int a[2] ; // a == &a == 0x001234 foo(a); // address of a (0x001234) goes to call stack, // this value is stored in 0x00122C // now inside foo(), &a == 0x00122C , a == 0x001234 } 
+2
source

All Articles