I met some problems when passing 2d-array to functions today, later I found some solutions like A and B. I knew that 2d-array is stored in a continuous memory as 1d. So in my opinion, there is no 2 dimensional points in fact, compiler split this continuous numbers and made '2 dimensional' concept.
My question is: in C after I explicitly told compiler the parameter is a 'int**', why it did not pass a '2 dimensional' point?
Someone may point out "in C you did not told compiler the group-length", I think it knew this information because if you t开发者_StackOverflowry to reexplain the 12 elements' plain memory into arr[2][6] it will be error like "void printArr(int _arr[][6], int _columns, int _rows)".
A little confused please help...
int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}};
void printArr(int _arr[][3], int _columns, int _rows){ //----->A
void printArr(int (* _arr)[3], int _columns, int _rows){//---->B
void printArr(int** _arr, int _columns, int _rows){//--------->C
for(int r=0; r< _rows; r++){
for (int c=0; c<_columns; c++)
//printf("%4d,", _arr[r][c]);
printf("%4d,", *(*(_arr+r)+c));
}
}
int main(){
printArr(arr, columns, rows);
}
Arrays decay into pointers, that means if you have an array of arrays int arr[x][y]
it can decay into a pointer to array int (*arr)[y]
.
int ** arr
therefore would be a version of decayed array of pointers int *arr[x]
, which is an incompatible type with your array.
int ** is a pointer to a pointer to int, not a pointer to a 2-dim array.
Style note: don't use leading underscores for your identifiers; such names are reserved for the implementation.
Solution B
explicitly captures what is happening; in the call to printArr
, the expression arr
is implicitly converted from "4-element array of 3-element array of int" to "pointer to 3-element array of int".
However, in the context of a function parameter declaration, the notation T a[]
is synonymous with T *a
; therefore, solution A
is effectively the same as solution B
.
You are right that the compiler reserves a contiguous block of memory so knowing that you can do something like my example. It also works with 1d arrays, ie: printArr((int*)arr, 1, 10);
void printArr(int *_arr, int _columns, int _rows) {
for(int r = 0; r < _rows; r++) {
for (int c = 0; c < _columns; c++) {
printf("%4d,", _arr[r * _columns + c]);
}
}
}
int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}};
printArr((int*)arr, 3, 4);
I think you were very close with C. The two changes are parameterizing with int* rather than int** and your offset computation was incorrect.
精彩评论