问题
A simple question about the C programming language (ANSI-C):
Are the multi-dimensional arrays in C jagged?
I mean - are we talking about "array of arrays" (one array of pointers to other addresses in the memory) , or this is just "long one-dimensional array" (which is stored sequentially in the memory)?
What that bothers me is that I'm kinda sure that:
matrix[i][j] is equivalent to * (  *  (matrix + i) + j)
回答1:
A multidimensional array in C is contiguous. The following:
int m[4][5];
consists of 4 int[5]s laid out next to each other in memory.
An array of pointers:
int *m[4];
is jagged. Each pointer can point to (the first element of) a separate array of a different length.
m[i][j] is equivalent to *(*(m+i)+j). See the C11 standard, section 6.5.2.1:
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))
Thus, m[i][j] is equivalent to (*(m+i))[j], which is equivalent to *(*(m+i)+j).
This equivalence exists because in most contexts, expressions of array type decay to pointers to their first element (C11 standard, 6.3.2.1). m[i][j] is interpreted as the following:
- mis an array of arrays, so it decays to a pointer to- m[0], the first subarray.
- m+iis a pointer to the- ith subarray of- m.
- m[i]is equivalent to- *(m+i), dereferencing a pointer to the- ith subarray of- m. Since this is an expression of array type, it decays to a pointer to- m[i][0].
- m[i][j]is equivalent to- *(*(m+i)+j), dereferencing a pointer to the- jth element of the- ith subarray of- m.
Note that pointers to arrays are different from pointers to their first element. m+i is a pointer to an array; it is not an expression of array type, and it does not decay, whether to a pointer to a pointer or to any other type.
回答2:
A consecutive memory area:
int arr[N][M];
A non-consecutive memory area:
int** arr = malloc(N*sizeof(int*));
for (int i=0; i<N; i++)
    arr[i] = malloc(M*sizeof(int));
You can use arr as a 2-dimensional array (e.g., arr[1][2] = 3) in both cases. But you can safely apply larger copy operations, such as memset(arr,0,N*M*sizeof(int)), only in the first case.
回答3:
This would depend.
Multidimensional arrays in C are sequentially arranged.
You can create jagged arrays if you want using pointers.
回答4:
If you declare a multi-dimensional array, you get "long one-dimensional array" (which is stored sequentially in the memory).
If you declare a pointer to pointer (to pointer....) you get arrays of arrays.
This difference is a source of much confusion for beginner C programmers.
回答5:
An array or arrays, such as int matrix[A][B] is not jagged, as each element of matrix is an array of B int.
You want to know that the outcome of *(*(matrix+i)+j) is and compare it to the outcome of matrix[i][j].
Since the type of matrix is array of A array of B int, then the expression matrix+i is a pointer that points to the ith array of B int of matrix, and its type is int (*)[B]. Dereferencing this expression results in an array of B int. The expression *(matrix+i)+j) results in a pointer to the jth int of that array. Dereferencing that expression results in an int. This is equivalent to what the expression matrix[i][j] would do.
An array of pointers, such as int *matrix[A], may be jagged, as each element of matrix may point to a different sized allocation.
回答6:
You are right, that matrix[i][j] is equivalent to *(*(matrix + i) + j), since arr[i] is equivalent to *(arr + i). However, please keep in mind, that if arr is declared as
int arr[64];
then any reference to arr may be implicitly converted to &arr[0], that is a pointer to the first element. Same thing happens with arrays of arrays:
int matrix[8][8];
Here matrix has type int[8][8], which is automatically converted to int (*)[8] when you add an integer to it, as in matrix + i. Then *(matrix + i) has type int[8], which is again converted to int * when you add j, so *(matrix + i) + j has type int *, therefore *(*(matrix + i) + j) has type int as expected.
So the point is, that arrays are not pointers, it is just that they can be implicitly casted to a pointer to their first element.
So if you allocate arrays of arrays like above (int matrix[8][8];), then then all elements are consecutive in memory.
来源:https://stackoverflow.com/questions/21624873/multi-dimensional-arrays-in-c-are-they-jagged