开发者

a and &a differs for an array passed as a function parameter in C

Why do the values of a and &a differ for a array passed as a function parameter? b and &b do not differ for an array defined within a function body. The 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 all the discussion, I understand the following is happening:

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开发者_Go百科. */
                          /* since the stack grows from higher to lower addresses, */
                          /* the value of '&a' is always lower than a. */


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

I would have to look for the particular quote from the standard, but when a function signatures are being analyzed, an argument of type array of N elements of type T is converted to pointer to T. When you later type foo(a), a decays into a pointer to the address of the first element, which is copied. Inside foo you are comparing the value of a pointer to 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 within scope as 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 the 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 that syntax and use the pointer syntax, you will get less surprises
  • identifiers that denote an array decay 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)
}


An array is not a pointer. It evaluates to a pointer in almost all context, 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 there evaluates to the address of the first element &(a[0]) that is passed to the function.

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

Inside the function &a is something different. Here a is a "pointer to basetype" so &a is of type "pointer to pointer to basetype" and the address that you see is the address of the pointer on the stack and not of your original array.


When you pass a parameter by reference to a function, you technically put an address of the element into function call stack. When you use & with function parameter , you get the address of that value. I'll try to illustrate it (all addresses are arbitrary, for demonstration only):

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


}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜