int main()
{
matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
int **ptr = (int**)matrix;
printf("%d%d",*开发者_运维技巧*matrix,*ptr);
}
But when a 2-d array is passed as a parameter it is typecasted into (*matrix)[2] .. what type does the compiler store this array as... is it storing as a 2-d array or a double pointer or an pointer to an array .. If it is storing as an array how does it interprets differently at different situations like above. Please help me understand.
Is 2d array a double pointer?
No. This line of your program is incorrect:
int **ptr = (int**)matrix;
This answer deals with the same topic
If you want concrete image how multidimensional arrays are implemented:
The rules for multidimensional arrays are not different from those for ordinary arrays, just substitute the "inner" array type as element type. The array items are stored in memory directly after each other:
matrix: 11 22 33 99 44 55 66 110
----------- the first element of matrix
------------ the second element of matrix
Therefore, to address element matrix[x][y]
, you take the base address of matrix + x*4 + y
(4 is the inner array size).
When arrays are passed to functions, they decay to pointers to their first element. As you noticed, this would be int (*)[4]
. The 4
in the type would then tell the compiler the size of the inner type, which is why it works. When doing pointer arithmetic on a similar pointer, the compiler adds multiples of the element size, so for matrix_ptr[x][y]
, you get matrix_ptr + x*4 + y
, which is exactly the same as above.
The cast ptr=(int**)matrix
is therefore incorrect. For once, *ptr
would mean a pointer value stored at address of matrix, but there isn't any. Secondly, There isn't a pointer to matrix[1]
anywhere in the memory of the program.
Note: the calculations in this post assume sizeof(int)==1
, to avoid unnecessary complexity.
No. A multidimensional array is a single block of memory. The size of the block is the product of the dimensions multiplied by the size of the type of the elements, and indexing in each pair of brackets offsets into the array by the product of the dimensions for the remaining dimensions. So..
int arr[5][3][2];
is an array that holds 30 int
s. arr[0][0][0]
gives the first, arr[1][0][0]
gives the seventh (offsets by 3 * 2). arr[0][1][0]
gives the third (offsets by 2).
The pointers the array decays to will depend on the level; arr
decays to a pointer to a 3x2 int array, arr[0]
decays to a pointer to a 2 element int array, and arr[0][0] decays to a pointer to int.
However, you can also have an array of pointers, and treat it as a multidimensional array -- but it requires some extra setup, because you have to set each pointer to its array. Additionally, you lose the information about the sizes of the arrays within the array (sizeof
would give the size of the pointer). On the other hand, you gain the ability to have differently sized sub-arrays and to change where the pointers point, which is useful if they need to be resized or rearranged. An array of pointers like this can be indexed like a multidimensional array, even though it's allocated and arranged differently and sizeof
won't always behave the same way with it. A statically allocated example of this setup would be:
int *arr[3];
int aa[2] = { 10, 11 },
ab[2] = { 12, 13 },
ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;
After the above, arr[1][0]
is 12
. But instead of giving the int
found at 1 * 2 * sizeof(int)
bytes past the start address of the array arr
, it gives the int
found at 0 * sizeof(int)
bytes past the address pointed to by arr[1]
. Also, sizeof(arr[0])
is equivalent to sizeof(int *)
instead of sizeof(int) * 2
.
In C, there's nothing special you need to know to understand multi-dimensional arrays. They work exactly the same way as if they were never specifically mentioned. All you need to know is that you can create an array of any type, including an array.
So when you see:
int matrix[2][4];
Just think, "matrix
is an array of 2 things -- those things are arrays of 4 integers". All the normal rules for arrays apply. For example, matrix
can easily decay into a pointer to its first member, just like any other array, which in this case is an array of four integers. (Which can, of course, itself decay.)
If you can use the stack for that data (small volume) then you usually define the matrix:
int matrix[X][Y]
When you want to allocate it in the heap (large volume), the you usually define a:
int** matrix = NULL;
and then allocate the two dimensions with malloc/calloc. You can treat the 2d array as int** but that is not a good practice since it makes the code less readable. Other then that
**matrix == matrix[0][0] is true
精彩评论