# 2D arrays

• 12-20-2009
2D arrays
So i can't seem to figure this one out. How do i pass a 2D array to a function by reference, or as a pointer, or any way that will allow me to edit it and have it change the original? I guess a better description would be. I have a multiple classes that need to access and edit the contents of a 2d array. so how can i have each class store a pointer or a reference to the main array so that they can read and edit it?
• 12-21-2009
laserlight
Quote:

How do i pass a 2D array to a function by reference, or as a pointer, or any way that will allow me to edit it and have it change the original?

If you are trying to change the array itself, then that is not possible as you cannot assign to an array. If you are trying to change the contents of the array, then the same idea applies: when passed as an argument, an array is converted to a pointer to its first element. It so happens that in this case the first element is itself an array.
• 12-21-2009
yea, i meant to say, to change the contents of the array. Could you show an example of how this is done?
• 12-21-2009
laserlight
Well... don't you know how to change the contents of a 1D array using a pointer to its first element? It is not that much different, except that you would be changing an element of an element of the 2D array.
• 12-21-2009
if i understand you correctly you mean something like this?:
Code:

```void foo(int **t) {     int **temp;     temp = t;     *temp[1] = 1; } void main() {     int an_array[3][2] = {{0,0,0},{0,0,0}};     foo(an_array);     return 0; }```
when i try this it says
Code:

`error: cannot convert ‘int*’ to ‘int**’ for argument ‘1’ to ‘void test(int**)’`
i can get it to work with a 1d array...
• 12-21-2009
laserlight
Actually, I mean something like this:
Code:

```void foo(int t[][3]) {     t[0][1] = 1; } int main() {     int an_array[2][3] = {{0,0,0},{0,0,0}};     foo(an_array);     return 0; }```
Notice that the parameter is a pointer to an array of 3 ints, not a pointer to a pointer. I changed an_array to be an array of 2 arrays of 3 ints, since that corresponds to the initialiser that you used.
• 12-21-2009
ok, but lets say that foo is a class instead of a function. How can i get it to keep, a reference to the original, so that at a later time foo can change the original without needing to pass it as a reference again?
• 12-21-2009
laserlight
Quote:

ok, but lets say that foo is a class instead of a function. How can i get it to keep, a reference to the original, so that at a later time foo can change the original without needing to pass it as a reference again?

You can do the same thing: store a pointer to the first element of the 2D array. The syntax would be the more complicated looking:
Code:

```class Foo { public:     // ... private:     int (*t)[3]; };```
but in the end the t member variable is just a pointer to an array of 3 ints.

A warning though: you have to be careful that the array still exists. It is possible that the 2D array is destroyed before the Foo object is destroyed, in which case the t member variable would point to an array that no longer exists.
• 12-21-2009
it seems the error i was makeing is that i was trying to do int *array[3] instead of int (*array)[3] whats the difference?
• 12-21-2009
IceDane
Quote:

it seems the error i was makeing is that i was trying to do int *array[3] instead of int (*array)[3] whats the difference?

int *array[3] = pointer to an array of 3 ints.
int (*array)[3] = an array of 3 pointers to ints
• 12-21-2009
laserlight
Eh, IceDane mixed them up. It should be:
int *array[3] = an array of 3 pointers to ints
int (*array)[3] = pointer to an array of 3 ints.
• 12-21-2009
IceDane
Quote:

Originally Posted by laserlight
Eh, IceDane mixed them up. It should be:
int *array[3] = an array of 3 pointers to ints
int (*array)[3] = pointer to an array of 3 ints.

Oh, ..........

Really? That is almost counter-intuitive, if you ask me. The parenthesis in the latter are begging to be read first, thus "pointer to int" and then "[3]" = array of 3 = array of 3 pointers to int.

Ah well.
• 12-21-2009
grumpy
Quote:

Originally Posted by IceDane
Oh, ..........

Really? That is almost counter-intuitive, if you ask me. The parenthesis in the latter are begging to be read first, thus "pointer to int" and then "[3]" = array of 3 = array of 3 pointers to int.

Ah well.

The joys of the syntax .... arrays of pointers and pointers to arrays are concepts that require some effort to understand ..... any syntax that could be chosen will be obvious to someone but will be counter-intuitive to someone else.

The logic in "int (*array)[3];" is (roughly) that (*array) is an array of three ints. So array is a pointer to an array of three ints.

Whereas, in "int *array[3];" array is .... an array of three elements that point at an int.

Whether that's intuitive or not is a topic for discussion over a beer .... preferably after many beers.
• 12-21-2009
Elysia
Quote:

Originally Posted by IceDane
Oh, ..........

Really? That is almost counter-intuitive, if you ask me. The parenthesis in the latter are begging to be read first, thus "pointer to int" and then "[3]" = array of 3 = array of 3 pointers to int.

Ah well.

It shouldn't be.
Let's look at some examples.

int n[3];

Well all know what this is. It's an array of 3 ints, right? What's left of the name, n, is the type of the array, yes?
Let's add a * to that:

int* n[3];

Now we see that it's still an array. But this time it's an array of int*, right?
If we then consider a special syntax, of a pointer to an array to be:

int (*)[3];

...And then we add the name inside there, and we get

int (*n)[3];

Makes more sense then. Right?
• 12-21-2009
IceDane
Quote:

Originally Posted by Elysia
It shouldn't be.
Let's look at some examples.

int n[3];

Well all know what this is. It's an array of 3 ints, right? What's left of the name, n, is the type of the array, yes?
Let's add a * to that:

int* n[3];

Now we see that it's still an array. But this time it's an array of int*, right?
If we then consider a special syntax, of a pointer to an array to be:

int (*)[3];

...And then we add the name inside there, and we get

int (*n)[3];

Makes more sense then. Right?

Ah, yes. It does with the * at the type, not at the variable. I see why C++ people want to do that.

Thanks. That was pretty embarrassing. I should know this stuff.