1. Pointers to Multidimensional Arrays

I am not entirely clear on how to do pointers to multidimensional arrays. It seems that if p is a pointer to the first element of the multidimensional array then you cannot properly use the "p[i][j]" notation (my compiler returns an error, something along the lines of "subscripted value is neither an array nor a pointer"). Instead, you have to do a pointer to the first element of the array viewed as a 1-dim array of 1-dim arrays, which makes the typedefs somewhat more complicated. Furthermore, if you have a function which only knows the pointer to the first real element, you cannot use this trick and you have to do some arithmetic to work out the value. I am sure there must be a better way to do this.

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

typedef int Test[8];

int *TestFn(int *t)
{
t[11] = 4;
return t;
}

int main ()
{
Test *p;
Test k[8];
int *t;

p = &k[0];
t = &k[0][0];

t = TestFn(t);

printf("%d", p[1][3]);

getchar();
return 0;
}```
This prints the correct answer of 4, but:

1. The line "t[11] = 4" is rather cryptic. Obviously we know it is right because 1*8 + 3*1 = 11, but someone else might not know. Is there a way to put a double subscript to show the actual array position? As I commented earlier, "t[1][3]" doesn't seem to work.
2. It is not entirely clear that k is a two-dim array. Obviously I would like to have a definition like:

Code:
`int k[8][8];`
but I then could not see what type to set p as. Is there a better way around this one too?

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

void TestFn(int t[8][8])
{
t[1][3] = 4;
}

int main ()
{
int k[8][8];
TestFn(k);
printf("%d", k[1][3]);
getchar();
return 0;
}```
Arrays are passed as a pointer anyway, so returning the pointer doesn't usually buy much.

3. Hi, thanks for your quick reply. Unfortunately that was not what I was asking. I wondered how you would access, for example the [1][3] element of an array if you only had a pointer to the [0][0] element. Your solution modified my function to take as its argument a multidimensional array rather than a pointer, however that was not what I was asking. For example, what if you didn't have the actual array to pass, for instance if it was created by malloc?

4. Two dimensional arrays are not the same as a pointer to a pointer type, and any function getting passed a two dimensional array needs to know at least the last field, eg.
Code:
`void foo(char a[][5])`
The compiler then knows how to calculate the correct addresses.

Any long explanation I try to offer here would be inadequate compared to the comp.lang.c FAQ section on arrays and pointers.

Pay particular attention to questions 6.16 (dynamic multidimensional array), 6.18, 6.19, 6.20.

5. Originally Posted by cwr
Two dimensional arrays are not the same as a pointer to a pointer type, and any function getting passed a two dimensional array needs to know at least the last field, eg.
Code:
`void foo(char a[][5])`
The compiler then knows how to calculate the correct addresses.

Any long explanation I try to offer here would be inadequate compared to the comp.lang.c FAQ section on arrays and pointers.

Pay particular attention to questions 6.16 (dynamic multidimensional array), 6.18, 6.19, 6.20.
So hold on, let me get this straight. I can create a function

Code:
`void f(int a[][5])`
expecting an ARRAY, then pass it a pointer?

Code:
```int a[10][5];
f(&a[0][0]);```
Is this correct?

6. Originally Posted by kidburla
Is this correct?
No, the function call would simply be:

Code:
`f(a);`

7. ...

Originally Posted by kidburla
Hi, thanks for your quick reply. Unfortunately that was not what I was asking. I wondered how you would access, for example the [1][3] element of an array if you only had a pointer to the [0][0] element. Your solution modified my function to take as its argument a multidimensional array rather than a pointer, however that was not what I was asking. For example, what if you didn't have the actual array to pass, for instance if it was created by malloc?
Well, if all you want is a pointer to the [0][0] element in a two-dimensional array, you'd simply need to do this:

char arrr[5][10];
char *p = &arr[0][0];

*p = 's';

putchar(arr[0][0]); // outputs character: s

But after rereading your question, I see you meant something quite diffrent. In that case, you would need a pointer to the whole two-dimensional array, not the element. To access the n index of the two-dimensional array (read: arr[n]) you would first create and initialize a pointer to a two-dimensional array with (we'll be using my example above) 10 elements in lenght, that's for the length in each array of the two-dimensional array. Also, the last index in the two-dimensional array (read: arr[FIRST_INDEX][LAST_INDEX]) is the key component here when you want to create a pointer to this object or pass it around to another function. The compiler, or rather C, needs to know how many elements over it needs to jump in order to get to the next index/array when you do something like arr[1].

To further elaborate; to go from arr[0] to arr[1], I'll repeat: the compiler needs to know how many elements over it needs to jump in order to get to that particular index/array, thus, this is why need to provide "the pointer to the two-dimensional array" the lenght of an array in our two-dimensional array (which would be 10 in our example). let me demonstrate the pointer notation now:

Code:
```int main(int argc, char **argv)
{
char arr[5][10];
char (*ip)[10]; // ip is a pointer to an array of 10 character elements

ip = arr;

getchar();
return 0;
}```
If this is hard to comprehend, let me ask you this: when you do this:

char norm_array[5]; //normal array
char *p = norm_array; // normal pointer, to array

You need not do this:

char (*p)[5] = norm_array; // <- a pointer to an array of 5 character elements.

It reads sensible, no?. You have a pointer to an array of 5 char elements, which is what we got; an array of 5 char elements. But why do we not need to specify it as I just now did in pointer notation? Because when you do p[2] (with the _normal_pointer_), C knows how many elements to jump over to the next index/element. The keyword char in the pointer, automatically tells C that it only needs to jump n sizeof(char) over but when you have a two-dimensional array, and you create a _normal_pointer_ to it, C only knows the sizeof(char) but what about the LAST_INDEX? How does C know how many index(s)/elements(s) over it needs to jump to ge to the next index/array with only sizeof(char)? It needs a second piece of information, and that is the length of the LAST_INDEX, and it's why need to do this: char (*ip)[LAST_INDEX]; That's it, C does not need to know the FIRST_INDEX because it already knows it by the type of the object, which in this case; it's the keyword char.

I hope this helped you understand this tough subject better. Keep on practicing and you'll eventually get it. Trust me

8. Originally Posted by kidburla
So hold on, let me get this straight. I can create a function

Code:
`void f(int a[][5])`
expecting an ARRAY, then pass it a pointer?

Code:
```int a[10][5];
f(&a[0][0]);```
Is this correct?
When you refer to an array by itself, just the name, it becomes a non-modifiable pointer anyway.

Indeed, a[0] is equivalent to *(a + 0), so &a[0][0] is just cancelling the * out to just leave a. As said above, it would just be f(a);

9. Originally Posted by hk_mp5kpdw
No, the function call would simply be:

Code:
`f(a);`

But I SAID when you only knew the pointer to the [0][0] element. I need to be passing a pointer, not the entire array. Passing the array is not what I'm interested in, I already know how to do that.

10. Originally Posted by kidburla
But I SAID when you only knew the pointer to the [0][0] element. I need to be passing a pointer, not the entire array. Passing the array is not what I'm interested in, I already know how to do that.