Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

arrays

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. */
                          /* since the stack grows from higher to lower addresses, */
                          /* the value of '&a' is always lower than a. */
like image 203
nitzs Avatar asked Feb 28 '11 15:02

nitzs


People also ask

What is A and W stand for?

Allen partnered with former Lodi employee Frank Wright. They leased their first two Root Beer stands to other operators so they could expand into the larger city of Sacramento. This was around the same time the partners coined the new name A&W®, “A” for Allen & “W” for Wright.

Where did A and W originate?

1) A&W was founded on June 20, 1919 in Lodi, California, with the first mug of Root Beer served at a homecoming parade for World War I veterans; it was the first U.S. chain restaurant to expand to Southeast Asia (1963).

When did A&W leave Singapore?

By then, A&W was facing stiff competition and eventually closed down in Singapore in 2003.

Is A&W American or Canadian?

Since that time, A&W has always been owned and operated in Canada independently from A&W operations in the United States. In 1995, the company's then current senior management team along with other investors acquired A&W Food Services in a management buy-out of the A&W business from Unilever Canada Limited.


1 Answers

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)
}
like image 52
David Rodríguez - dribeas Avatar answered Nov 07 '22 06:11

David Rodríguez - dribeas