# Multidimensional arrays

Show 80 post(s) from this thread on one page
Page 1 of 4 1234 Last
• 09-04-2009
Niels_M
Multidimensional arrays
Hi all

I am a little confused about multidimensional arrays. Please look at this

Code:

`char mda[][10] = {"one", "two", "three"};`
Can you explain to me, why multidimensional arrays with characters must be defined like the above method? Why can't I just write

Code:

`char mda[][] = {"one", "two", "three"},`
i.e. char (mda[])[] = {...}, so an array, where each element is an array?
• 09-04-2009
Sebastiani
When you index into a multi-dimensional array the compiler can't simply infer the offset into the data - it needs to know the dimensions a priori in order to calculate it. For example, let's say you want the character at mda[ 3 ][ 5 ]. The compiler has to know the distance between mda[ 2 ] and mda[ 3 ] before it can generate the offset. Without specifying the second dimension (eg: columns) this is essentially impossible. Consider now if you had declared it as char mda[][11]. When you ask for mda[ 3 ][ 5 ] the compiler calculates ( 3 * 11 ) + 5 and adds this to the base address of mda to locate the character.

Incidentally, you can declare an array of pointers if you don't want to fuss with the second dimension:

Code:

`char const* mda[] = {"one", "two", "three"};`
Just keep in mind that assigning a pointer to a string literal means that the data is read-only. If you need to write to the data, you'll need to allocate some memory to each pointer.
• 09-04-2009
Niels_M
Thank you for replying. May I ask how you got to "( 3 * 11 ) + 5"?
• 09-04-2009
tabstop
Multidimensional arrays are laid out in order in memory, starting with [0][0], then [0][1], then [0][2], ..., [0][11], [1][0], [1][1], and so on. So every step in the first dimension is actually 11 steps (for your specific case) total to get through the entire row.
• 09-04-2009
Niels_M
Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?

By the way, is a 1D-array a row of a column in C?
• 09-04-2009
A row.
• 09-04-2009
tabstop
Quote:

Originally Posted by Niels_M
Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?

No? You don't have to move any to get to the first element, because, well, that's where you already are.
• 09-04-2009
Sebastiani
Quote:

Originally Posted by Niels_M
Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?

No, arrays use 0-based indexes, so + 6 would set it to the past the element by 1.
• 09-05-2009
Niels_M
I see. Thanks.

When I pass a multidimensional array as a function parameter, then it is the address of the first element in the multidimensional array which is passed. In this case, this address points to an array (a row) as well.

So when we write e.g. f ( int (*a)[5]), then this means that *a is an integer pointer, which points to an array (a row) containing 5 integers (five colums)?

If the above is correct, then why is it that is it equivalent of writing f ( int a[][5])?
• 09-05-2009
Sebastiani
Quote:

Originally Posted by Niels_M
I see. Thanks.

When I pass a multidimensional array as a function parameter, then it is the address of the first element in the multidimensional array which is passed. In this case, this address points to an array (a row) as well.

So when we write e.g. f ( int (*a)[5]), then this means that *a is an integer pointer, which points to an array (a row) containing 5 integers (five colums)?

If the above is correct, then why is it that is it equivalent of writing f ( int a[][5])?

int (* a )[ 5 ] is a pointer to an array of an array of 5 elements (no, I am not repeating myself there!), if that makes sense. Had you declared it without parenthesis, it would have been an array of pointers to integers.
• 09-05-2009
Niels_M
Quote:

Originally Posted by Sebastiani
int (* a )[ 5 ] is a pointer to an array of an array of 5 elements (no, I am not repeating myself there!), if that makes sense. Had you declared it without parenthesis, it would have been an array of pointers to integers.

But why is it that the compiler allows for the decleration f ( int a[][5] )? Is it because the compiler interprets the "a[]"-part as (*a)?
• 09-05-2009
Sebastiani
Yes. Consider a single-dimension array:

Code:

`double values[16];`
Now you could pass it to either of these functions:

Code:

```void foo( double* data, size_t length ) {        } void bar( double data[ ], size_t length ) {        }```
So the functions essentially have the same signature.
• 09-05-2009
Niels_M
Thank you. I have one last question, and it is related to the above.

The following is not permitted in C

Code:

`int *test = {1,2,3} // not permitted`
since {1,2,3} is an initializer list, and *test is a pointer. In C we know that when a function is called, the copies of the arguments are made as if by assignment. In post #9 I wrote

Code:

`f ( int (*a)[5])`
where *a points to an array with 5 integer elements. Thus we are actually writing

int (*a)[5] = {1,2,3,4,5}.

Now, how can this paradox be explained?
• 09-05-2009
vart
Quote:

Originally Posted by Niels_M
Thus we are actually writing
Code:

`int (*a)[5] = {1,2,3,4,5}.`
Now, how can this paradox be explained?

We do no such thing, so no paradox here
• 09-05-2009
Niels_M
Quote:

Originally Posted by vart
We do no such thing, so no paradox here

I know that, but we know (as I wrote) that when a function is called, the copies of the arguments are made as if by assignment. So essentially what we have is

Code:

`int (*a)[5] = {1,2,3,4,5}.`
Show 80 post(s) from this thread on one page
Page 1 of 4 1234 Last