1. ## Multi-dimensjonal (char) array

Ok, I'm struggling a bit again. This time it's the concept of multi-dimensional char arrays.

A one-dimensional array works like this:
Code:
```char str[15];
string(str);

void string(char *str) {
printf("%s\n", str);
}```
However, when I create a multi-dimensional array and try to pass it to a function in the same way, like this:
Code:
```void mstring(char *);

char mstr[5][10];
string(mstr);

void mstring(char *mstr) {
// something
}```
I get the following warnings:

Code:
```warning: passing argument 1 of ‘mstring’ from incompatible pointer type (points to the line with the function call, string(mstr);)
note: expected ‘char *’ but argument is of type ‘char (*)[10]’ (points to the prototype for the mstring function)```
I'm _beginning_ to grasp the concept of pointers, but there's still a long way to go. However, I'm not sure if a two-dimensional array is a pointer to a pointer, or a pointer with pointers to arrays?

2. Originally Posted by cnewbie1
However, I'm not sure if a two-dimensional array is a pointer to a pointer, or a pointer with pointers to arrays?
mstr is an array of 5 arrays of 10 char. It is neither a pointer to a pointer nor a pointer with pointers to arrays. However, it can be converted to a pointer to an array of 10 char. This is still different from a pointer to a pointer, and certainly different from a pointer to a char.

For example:
Code:
```void foo(char (*y)[10]);

int main(int argc, char *argv[])
{
char x[5][10];
foo(x);
return 0;
}

void foo(char (*y)[10])
{
y[0][0] = '\0';
}```

3. It's a question of how you envision it...

If you have: char Strings[10][50]

You have 10 buffers (or lines) of 50 characters each.

Strings points to the first line first character Strings[0][0].

Strings[1] is actually a pointer to the second buffer, first character.

Strings[3][30] is the character at the 4th buffer, 31st position.

If it looks like I'm missing by one... I am. Don't forget that C arrays always index from 0, not 1.

4. Originally Posted by CommonTater
Strings points to the first line first character Strings[0][0].
No, it does not.

Strings is not a pointer to char, and also cannot be implicitly converted to a pointer to char, so cannot point at Strings[0][0].

If you want evidence of that, you will find that the test
Code:
`if (Strings == &(Strings[0][0])) {}`
will not even compile.

5. Ah, thanks a heap. So simple, really - I should've examined the warning(s) more closely.

I was confusing arras/pointers, of course, with that last question. Probably because of the relationship between arrays and pointers.

6. But, there's more:

When returning arrays from functions, this works:
Code:
```char *string2(char *);

char buf[15];
char str2 = *string2(buf);
printf("%s\n", buf);

char *string2(char *buf) {
strcpy(buf, "Textstring 2");
return buf;
}```
However, doing the same thing with a 2-dimensional array doesn't work:
Code:
```char *mstring2(char (*)[10]);

char mbuf[5][10];
char mstr2 = *mstring2(mbuf);

char *mstring2(char (*buf)[10]) {
// Do something...fill the arrays...
return buf;
}```
This gives:
Code:
`warning: return from incompatible pointer type`

7. Originally Posted by cnewbie1
However, doing the same thing with a 2-dimensional array doesn't work:
I suggest that you make use of a typedef, e.g.,
Code:
```#include <stdio.h>

typedef char string_type[10];

string_type *foo(string_type *y);

int main(void)
{
string_type x[5];
string_type *r = foo(x);
printf("%c\n", r[0][0]);
return 0;
}

string_type *foo(string_type *y)
{
y[0][0] = 'C';
return y;
}```

8. Thanks, laserlight. Typedef it is, then. I'm guessing, since you're suggesting that, it's not possible to pass a multi-dimensional array like I tried?

9. Originally Posted by CommonTater
Strings[1] is actually a pointer to the second buffer, first character.
You're thinking of an array of pointers - in this case, the entire array is one contiguous block of data.

Code:
```int main( void )
{
const int rows = 13, cols = 2;
char data[ rows ][ cols ];
int ltr = 'a';
for( int rdx = 0; rdx < rows; ++rdx )
{
for( int cdx = 0; cdx < cols; ++cdx )
{
data[ rdx ][ cdx ] = ltr++;
}
}
/*
Out of bounds?
*/
data[ 0 ][ 'j' - 'a' ] = '!';
for( int rdx = 0; rdx < rows; ++rdx )
{
for( int cdx = 0; cdx < cols; ++cdx )
{
putchar( data[ rdx ][ cdx ] );
}
putchar( '\n' );
}
}```

10. just put an asterisk before mstr. multidimensional arrays are address of address of (address of) something.

Code:
```void mstring(char *);

char mstr[5][10];
mstring(*mstr);   <----- there you go

void mstring(char *mstr) {
// something
}```

11. Originally Posted by scout
This is not true. Arrays are not pointers. A multidimensional array is an array of array (of array ...).

It's true that in almost all circumstances, an array decays into a pointer. But as has been mentioned, an array of array does not decay into a pointer to pointer; it decays into a pointer to an array. A multidimensional array is one of the cases where the difference between a pointer and an array is important.

12. scout: That works with a void method, as mentioned further up. But with a char method, receiving and returning a multi-dimensional array, I cannot get it to work that way. Using a typedef, however, worked beautifully.

13. Originally Posted by cnewbie1
scout: That works with a void method, as mentioned further up. But with a char method, receiving and returning a multi-dimensional array, I cannot get it to work that way. Using a typedef, however, worked beautifully.
mstring2 takes a multidimensional array and returns the same multidimensional array address (the mstr2 becomes a single array though). just play with it and hopefully it'll help. . yeah the typedef solution is sweet.

Code:
```#include <stdio.h>
#include <stdlib.h>

char *mstring2(char *);

int main(void)
{
char mbuf[5][10];
char *mstr2 = mstring2(*mbuf);  // takes a multidimensional array and returns multidimensional array (address)

printf("%p\n", mstr2);               // check if equal
printf("%p\n", &mbuf[0][0]);         //

printf("this should be 49 = %d\n",mbuf[4][9]);
printf("this should be 1 = %d\n",mbuf[0][1]);
char k = 'k';
char p = 'p';
*(mstr2+(4*10)+9) = 3;
*(mstr2+(0*10)+1) = k;
*(mstr2+(1*10)+1) = p;
printf("this should be 3 = %d\n",mstr2[49]);
printf("this should be 3 = %d\n",mbuf[4][9]);
printf("this should be k = %c\n",mbuf[0][1]);
printf("this should be p = %c\n",mbuf[1][1]);

getchar();
return 0;
}

char *mstring2(char *k) {

for (int i=0;i<50; i++)
{
*(k+i) = i;
}
return k;
}```