Yes, use array[position] , even if the parameter type is int *array . The alternative you gave ( *array[position] ) is actually invalid in this case, because the [] operator takes precedence over the * operator, which makes it equivalent to *(array[position]) , which is trying to dereference the value of a[position] , but not this address.
It gets a little more complicated for multidimensional arrays, but you can do this:
int m = 10, n = 5; int matrixOnStack[m][n]; matrixOnStack[0][0] = 0;
The way to interpret the matrixInHeap is that the "thing" that matrixInHeap points to is an array of n int values, so sizeof(*matrixInHeap) == n * sizeof(int) or the size of the entire row in the matrix. matrixInHeap[2][4] works because matrixInHeap[2] advances the matrixInHeap address by 2 * sizeof(*matrixInHeap) , which skips two full lines of integers n , which leads to the address of the third row, and then selects the final [4] the fifth element from the third row. (remember that array indices start at 0, not 1)
You can use the same type when pointing to regular multidimensional c-arrays (if you already know the size):
int (*matrixPointer)[n] = matrixOnStack || matrixInHeap;
Now let's say that you want to have a function that takes one of these variable sized matrices as a parameter. When the variables were declared earlier, the type had some size information (both dimensions in the stack example and the last dimension n in the heap example). Thus, the type of the parameter in the definition of the function will need the value of n , which we can really do if we include it as a separate parameter, defining such a function:
void fillWithZeros(int m, int n, int (*matrix)[n]) { for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) matrix[i][j] = 0; }
If we do not need the value of m inside the function, we could leave it completely until we save n :
bool isZeroAtLocation(int n, int (*matrix)[n], int i, int j) { return matrix[i][j] == 0; }
And then we just include the size when calling the functions:
fillWithZeros(m, n, matrixPointer); assert(isZeroAtLocation(n, matrixPointer, 0, 0));
This may seem a little like what we are working on compilers, especially in cases where we do not use n at all inside the function body (or only as a parameter for similar functions), but at least it works.
The final readability issue: using malloc(sizeof(int[len])) equivalent to malloc(len * sizeof(int)) (and anyone who tells you otherwise doesn't understand the layout of the structure in c), but the first way writing it makes it obvious to the reader that we are talking about an array. The same applies to malloc(sizeof(int[m][n])) and malloc(m * n * sizeof(int)) .