-1

What is the reason, that the first index in the function void transposeMatrix(int a[][arraySize]) is empty?

Alan
  • 589
  • 5
  • 29
saddam
  • 1

2 Answers2

3

Because what transposeMatrix receives really isn't a 2D array, but rather a pointer to a 1D array.

Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.

If you declare an array as

int arr[N][M];

and pass it to a function

void foo( arr );

then the expression arr is converted from type "N-element array of M-element array of int" to "pointer to M-element array of int" (int (*)[M]).

In a function parameter declaration, T a[N] and T a[] are "adjusted" to T *a - IOW, all three declare a as a pointer to T (this is only true for function parameter declarations).

Thus,

void transposeMatrix(int a[][arraySize])

is equivalent to

void transposeMatrix(int (*a)[arraySize])

Using a[][M] rather than (*a)[M] is a notational convenience (similar to using p->m instead of (*p).m for accessing struct and union members through pointers).

Because of how array indexing works, you can index into a like any other 2D array. Remember that the subscript operation a[i] is defined as *(a + i) - given a starting address a, find the address of the i'th element (not byte) following a and dereference the result. So:

(*a)[i] == (*(a + 0))[i] == (a[0])[i] == a[0][i]

meaning

(*(a + j))[i] == (a[j])[i] == a[j][i]
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • How is the automatic conversion of an array to a pointer relevant? Suppose arrays were not automatically converted to pointers. Then, when an array `a` is passed to a function, it would have to be passed by some other mechanism, such as by reference or by copy, although other methods are possible. If it were a very small array, for example, such as `char[n][2]` for n≤4, it could be passed entirely in an eight-byte register, as some ABIs do for small structs. And the called routine would not need to know n. So it is not conversion to a pointer that enables the first dimension to be omitted. – Eric Postpischil Jul 20 '18 at 02:49
0

When you have an array a of n objects of type foo, the compiler can calculate the location of element a[i] by adding i times the size of a foo object to the starting address of a.

Note that this calculation involves only the size of foo and the subscript i. It does not involve the number of elements n. The compiler does not need to know the number of elements in order to calculate where an element is.

You would need to know the number of elements in an array to avoid going beyond the end of an array. However, in C, it is not the compiler’s job to guard against going beyond the end of the array. The author of the function is responsible for doing that. So, for this purpose, the compiler does not need to know how many elements are in an array.

Now suppose each foo object is itself an array of m objects of type bar. The compiler does need to know the size of a foo object. How big is a foo? Since a foo is an array of m objects of type bar, its size is m times the size of bar. So, to know how big a foo is, the compiler needs to know how many elements in in the array.

Thus, when passing an int a[FirstDimension][SecondDimension], the compiler does not need to know FirstDimension but does need to know SecondDimension.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312