user4418808
user4418808

Reputation:

What is the difference between `a` and `*a` where `a` denotes a 2D array?

Pointers and arrays are closely associated with each other, so, if we have a 2-D array

int a[3][4]={
             1,2,3,4,
             5,6,7,8,
             9,10,11,12};

Both

printf("%p\n", a);

and

printf("%p\n", *a);

print the same address. What I understand is maybe a is pointing to the base address of a while *a is pointing to the first sub-array of the two-dimensional array a.

So, what is the difference between the two?

Upvotes: 4

Views: 294

Answers (5)

John Bode
John Bode

Reputation: 123458

Given the declaration

int a[3][4];

the following are true:

Expression     Type            Decays to        Value
----------     ----            ---------        -----
         a     int [3][4]      int (*)[4]       Base address of array
        &a     int (*)[3][4]   n/a              Base address of array
        *a     int [4]         int *            Base address of first subarray
                                                (equivalent to a[0])
      a[i]     int [4]         int *            Base address of i'th subarray
     &a[i]     int (*)[4]      n/a              Base address of i'th subarray
     *a[i]     int             n/a              Value of a[i][0]
   a[i][j]     int             n/a              Value of a[i][j]
  &a[i][j]     int *           n/a              Address of a[i][j]

The address of the first element of the array is the same as the address of the array itself, so the expressions a, &a, *a, a[0], &a[0], and &a[0][0] all yield the same value (the address of the first element of the array), but they will have different types (int (*)[3][4] vs. int (*)[4] vs. int *).

Edit

Except when it is the operand of the sizeof or unary & operators, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T" and the value of the expression will be the address of the first element of the array.

So the expression *a is equivalent to a[0]; both expressions have type "4-element array of int". Since they're not operands of the sizeof or unary & operators, those expressions "decay" to type "pointer to int".

That's what the "Decays to" column shows.

See section 6.3.2.1 of the online C 2011 language standard.

Upvotes: 4

Serge Ballesta
Serge Ballesta

Reputation: 148890

a is a 2D array of size 3x4. That means:

  • sizeof(a) == 3*4*sizeof(int)
  • a[i] is a 1D array of size 4 (for 0<=i<3)
  • a[i][j] is an int ( 0<=i<3 and 0<=j<4)
  • when used as a pointer a decays to &a[0]

*a is a[0]: it is a 1D array of size 4. That means :

  • sizeof(*a) == 4*sizeof(int)
  • (*a)[i] is an int (0<=i<4)
  • when used as a pointer *a decays to &a[0][0]

So a and *a are different objects that decay to pointers to the same address which is also &a. But a decays to a pointer to int[4], whereas *a decays to a pointer to int (thanks to undur_gongor for noticing).

Upvotes: 3

Naman Sogani
Naman Sogani

Reputation: 949

It is very simple. *a is an array of integers. In your case *a in nothing but the array [1,2,3,4]. Individual elements of this array can be accessed by (*a)[i], where i is the index of the required element.

And a is pointer to this array of integers. a[0] will give you the first array (it is same as *a), a[1] will give you the second array(which is [5,6,7,8]).

For example if you want to access 5th element(which is 5), it will a[1][0].

Upvotes: 0

undur_gongor
undur_gongor

Reputation: 15954

The difference between the pointers (that the arrays decay to) is not the address but the type.

As you have seen, both pointers point to the same address. But a points to sub-arrays whereas *a points to ints.

This makes a difference, e.g. when doing address arithmetic. a + 1 is something different than *a + 1.

Upvotes: 1

Quentin
Quentin

Reputation: 63124

What i get is may be a is pointing to the base address of a while *a is pointing to the first sub-array of two-dimensional array a.

That's almost it.

  • a on its own decays to a pointer (of type int(*)[3]) to its first subarray when you pass it to printf.
  • *a designates a's first subarray (of type int[3]), and decays to a pointer (of type int*) to the first element of that subarray.

In the end, they share the same value because an array has the same address as its first element, recursively.

Upvotes: 5

Related Questions