Array to pointer decay and passing multidimensional arrays to functions

[亡魂溺海] 提交于 2019-11-26 11:45:59

You got it slightly wrong: moreThings also decays to a pointer to the first element, but since it is an array of an array of chars, the first element is an "array of 8 chars". So the decayed pointer is of this type:

char (*p)[8] = moreThings;

The value of the pointer is of course the same as the value of &moreThings[0][0], i.e. of the first element of the first element, and also the same of &a, but the type is a different one in each case.

Here's an example if char a[N][3]:

+===========================+===========================+====
|+--------+--------+-------+|+--------+--------+-------+|
|| a[0,0] | a[0,1] | a[0,2]||| a[1,0] | a[1,1] | a[1,2]|| ...
|+--------+--------+-------+++--------+--------+-------++ ...
|            a[0]           |            a[1]           |
+===========================+===========================+====
                                    a
^^^
||+-- &a[0,0]
|+-----&a[0]
+-------&a
  • &a: address of the entire array of arrays of chars, which is a char[N][3]

  • &a[0], same as a: address of the first element, which is itself a char[3]

  • &a[0][0]: address of the first element of the first element, which is a char

This demonstrates that different objects may have the same address, but if two objects have the same address and the same type, then they are the same object.

Grijesh Chauhan

"ARRAY ADDRESS AND POINTERS TO MULTIDIMENSIONAL ARRAYS"

Lets we start with 1-D array first:

  • Declaration char a[8]; creates an array of 8 elements.
    And here a is address of fist element but not address of array.

  • char* ptr = a; is correct expression as ptr is pointer to char and can address first element.

  • But the expression ptr = &a is wrong! Because ptr can't address an array.

  • &a means address of array. Really Value of a and &a are same but semantically both are different, One is address of char other is address of array of 8 chars.

  • char (*ptr2)[8]; Here ptr2 is pointer to an array of 8 chars, And this time ptr2=&a is a valid expression.

  • Data-type of &a is char(*)[8] and type of a is char[8] that simply decays into char* in most operation e.g. char* ptr = a;

    To understand better read: Difference between char *str and char str[] and how both stores in memory?

Second case,

  • Declaration char aa[8][8]; creates a 2-D array of 8x8 size.

  • Any 2-D array can also be viewed as 1-D array in which each array element is a 1-D array.

  • aa is address of first element that is an array of 8 chars. Expression ptr2 = aa is valid and correct.

  • If we declare as follows:

    char (*ptr3)[8][8];    
    char ptr3 = &aa;  //is a correct expression
    

    Similarly,
    moreThings in your declaration char moreThings[8][8]; contain address of fist element that is char array of 8 elements.

    To understand better read: Difference between char* str[] and char str[][] and how both stores in memory?


It would be interesting to know:

  • morething is an address of 8 char array .

  • *morething is an address of first element that is &morething[0][0].

  • &morething is an address of 2-D array of 8 x 8.

    And address values of all above three are same but semantically all different.

  • **morething is value of first element that is morething[0][0].

    To understand better read: Difference between &str and str, when str is declared as char str[10]?

Further more,

  • void doThings(char thingsGoHere[8][8]) is nothing but void doThings(char (*thingsGoHere)[8]) and thus accepts any array that is two dimensional with the second dimension being 8.

About type of variables in C and C++: (I would like to add in answer)

  • Nothing is pass by reference in C its C++ concept. If its used in C that means author talking about pointer variable.
  • C supports pass by Address and pass by value.
  • C++ supports Pass by address, pass by value and also pass by Reference.

    Read: pointer variables and reference variables

At the end,

  • Name Of an array is constant identifier not variable.

Nicely explained by Kerrek,

In addition to that, we can prove it by the following example:

#include <stdio.h>

int main ()
{
 int a[10][10];

 printf (".. %p  %p\n", &a, &a+1);
 printf (".. %p  %p \n ", &a[0], &a[0]+1);
printf (".. %p   %p \n ", &a[0][0], &a[0][0] +1);
}

The Output is :

.. 0x7fff6ae2ca5c  0x7fff6ae2cbec    = 400 bytes difference
.. 0x7fff6ae2ca5c  0x7fff6ae2ca84    = 40 bytes difference
 .. 0x7fff6ae2ca5c   0x7fff6ae2ca60  = 4 bytes difference. 

&a +1 -> Moves the pointer by adding whole array size. ie: 400 bytes

&a[0] + 1 -> Moves the pointer by adding the size of column. ie: 40 bytes.

&a[0][0] +1 -> Moves the pointer by adding the size of element ie: 4 bytes.

[ int size is 4 bytes ]

Hope this helps. :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!