Archived

This topic is now archived and is closed to further replies.

how do i pass a multi dimensional array?

This topic is 5502 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok this totaly confuses me.. First I would like to pass it''s address because passing by value would take up too much memory. So say I have an array like this
  
#include <iostream>

using namespace std;

void SomeFunc( int *array[][5] );


int main()
{
	int array[5][5];

	for( int i = 0; i < 5; i ++ )
	{
		for( int j = 0; j < 5; j ++ )
			array[i][j] = rand()%99;
	}

	SomeFunc( &array );

	return 0;
}


void SomeFun( int *array[][5] )
{
}


C:\prog\test\driver.cpp(18) : error C2664: ''SomeFunc'' : cannot convert parameter 1 from ''int (*)[5][5]'' to ''int *[][5]''
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

test.exe - 1 error(s), 0 warning(s)

  
ok I can''t figure out how to pass multidimensional arrays also why do i need to include the second [5] in my declaration of SomeFunc but not the first. This is confusing

Share this post


Link to post
Share on other sites
Why would you try to use a pointer? Arrays are always passsed by reference.


          

void foo( int array[][5] )
{
// do something with array

}

int main( void )
{
int bar[5][5];

foo( bar );
}


arrays are stored row major, the compiler needs to know the number of columns in order to calculate the starting position of each row.



[My site|SGI STL|Bjarne FAQ|C++ FAQ Lite|MSDN|Jargon]
Ripped off from various people

[edited by - wild_pointer on November 21, 2002 12:56:39 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Buster
void Takes2DimArray(int **p) { }


That won't work because you'd lose column information, you'd either have to use

int array[][5]

as was said above, or

int (*array)[5]

which is actually what the first method is implicitly.

EDIT: Also, it's important to note that the above (which can be used like an array of colums), of course can have a varying number of rows. If you want to be sure that the person ONLY passes a 2 dimensional array with 5 rows and 5 columns, then you can do

int (&array)[5][5]

[edited by - Matt Calabrese on November 21, 2002 1:29:09 PM]

Share this post


Link to post
Share on other sites
So what your saying is if I pass an array by value it will actually pass it by reference?

and how is

int (*array)[5] == int array[][5]

?

I don''t understand

Share this post


Link to post
Share on other sites
quote:
Original post by ph33r
So what your saying is if I pass an array by value it will actually pass it by reference?


It''ll pass it by a pointer to the first element. There is no "copy constructor" for arrays (if you could call it that). You most likely already know that:

int array[5];
int otherarray[5] = array; //error

doesn''t work. The same goes for when you pass it to a function. You can''t implicitly pass an array by value.

So then what does happen? As I said, it passes the location of the first element. Whenever you use an array name in an expression (in almost all cases, excluding sizeof and what I''m about to explain later in this post, and probably some other various circumstances), you are actually refering to the address of the first element.

Example with single-dimensional arrays to make things easier:

void SomeFunc( int array[5] ); // The 5 here actually means nothing to the compiler and is ignored. You can pass an array of any length.
void SomeFunc( int array[] ); // The [] just means you are passing a pointer to an int.
void SomeFunc( int* array ); // Same thing as the previous two

The only reason that the [] syntax is there is so that someone reading the code knows that they are usually supposed to pass an array (though it is not necissary). For instance, if you wanted a function to search an array passed as a parameter for a certain value, you''d want to use the [] syntax, though you can still pass a pointer to a single instance of the datatype. If, on the other hand, your function just altered the value of an object that a pointer refers to, you''d more likely use * because it makes it more clear to the reader that you will only be altering one value. Of course, either syntax can be used for either case, and nothing can be assumed, but it makes it easier for someone glancing over the code to get a good idea on what they should pass (though, once again, not necissarily).

Using what I say above, you can understand that you can pass an array name to a function that takes a parameter that''s a pointer to the datatype the the array groups. So, let''s move onto multi-dimensional arrays.

What is:

int MyArray[5][10];

I know that''s a very vague question and can be interpereted multiple ways, but here''s what I mean:

MyArray is an array of 5 elements where each element is an array of ten int

From that, you may already understand where I''m going, but just to drive the nail in the coffin, think of that declaration of MyArray like this:

typedef int TenElementArray[10];
TenElementArray MyArray[5];

While it may not be apparent at first, both that declaration of MyArray and the one I provided earlier in this post are exactly the same. A multidimensional array can be looked at recursively with each dimension being an array of the next.

So, a 2 dimensional array is actually an array of arrays of the datatype of a fixed length.

Using that logic and relating it to what we said before:

int Array[5];

int* Pointer = Array;

Sets the Pointer to the address of the first element.

Well, let''s take that to the 2-dimensional MyArray that we defined. Using our second version of the declaration, we can see that:

typedef int TenElementArray[10];
TenElementArray MyArray[5];

TenElementArray* Pointer = MyArray;

Is, of course valid. This is because

&MyArray[0]

is the 0th element of the array of arrays of type int[10] which we type-defined as TenElementArray!

So, thinking logically, that means that

TenElementArray* Pointer;

creates a pointer to an array of 10 int. In other words, rather than writing it like this, we can rewrite it as:

int (*Pointer)[10];

Which is the syntax for creating a pointer to an array.

However, just like with our other example, this means that the number of rows doesn''t matter. So we could pass both

int MyArray[5][10];

To the function, as well as

int MyArray[50][10];

Because the number of rows doesn''t really matter!

... So what if you want to make sure that it is syntactically not valid to pass an array with a row count different than 5? That was exactly the point of the second part of my first post.

Once again, to better explain, I''ll take things first down to a single dimensional array:

int MyArray[5];

Earlier on in this post I explained how to make a true pointer to an array. So let''s just apply that knowledge here!

int MyArray[5];
int AnotherArray[6];

int (*SomeArray)[5];
SomeArray = &MyArray; // Works
SomeArray = &AnotherArray; // Doesn''t work, the array isn''t of length 5

Get it?

So let''s take that one more step into 2 dimensions

int MyArray[5][10];
int OtherArray[2][10]
int YetAnotherArray[5][4];

int (*SomeArray)[5][10];
SomeArray = &MyArray; // Works
SomeArray = &OtherArray; // Won''t work, not right dimensions
SomeArray = &YetAnotherArray; // Won''t work, not right dimensions

And there we have a perfectly valid, completely typesafe way of passing a multidimensional array to a function/store to a pointer.

Finally, To make it so you don''t have to explicitly use the address of operator, I made the declaration a reference instead of a pointer.

int MyArray[5][10];

int (&SomeArray)[5][10] = MyArray; // No need for address of operator!

Hope that cleared things up!

Share this post


Link to post
Share on other sites