Connecting Tech Pros Worldwide Forums | Help | Site Map

passing a 2d array as a paramater

laclac01@yahoo.com
Guest
 
Posts: n/a
#1: Aug 27 '05
Is there a way to pass a 2d array to a function in c++ with out having
to specifiy the number of elements in the array. Here is an example

Expand|Select|Wrap|Line Numbers
  1. #include<iostream>
  2. using namespace std;
  3.  
  4. int main()
  5. {
  6. int array[10][10];
  7. fill(array,rows,cols);
  8. return 0;
  9.  
  10. }
  11. void fill(int array[10][10], rows,cols)
  12. {
  13. int i, j;
  14.  
  15. for(i=0;i<10;i++)
  16. for(j=0;j<10;j++)
  17. array[i][j]=0;
  18. }
  19.  
array needs to have the [10][10] or at least
[][10]. is there a way i can make it so it
only needs [][]?


John Ratliff
Guest
 
Posts: n/a
#2: Aug 27 '05

re: passing a 2d array as a paramater


laclac01@yahoo.com wrote:[color=blue]
> Is there a way to pass a 2d array to a function in c++ with out having
> to specifiy the number of elements in the array. Here is an example
>
>
Expand|Select|Wrap|Line Numbers
  1. > #include<iostream>
  2. > using namespace std;
  3. >
  4. > int main()
  5. > {
  6. >    int array[10][10];
  7. >    fill(array,rows,cols);
  8. >    return 0;
  9. >
  10. > }
  11. > void fill(int array[10][10], rows,cols)
  12. > {
  13. >    int i, j;
  14. >
  15. >    for(i=0;i<10;i++)
  16. >    for(j=0;j<10;j++)
  17. >    array[i][j]=0;
  18. > }
> array needs to have the [10][10] or at least
> [][10]. is there a way i can make it so it
> only needs [][]?
>[/color]

I could be wrong, but I think no. This is because the compiler can't do
math on the pointer without knowing the secondary dimensions.

--John Ratliff
Kai-Uwe Bux
Guest
 
Posts: n/a
#3: Aug 27 '05

re: passing a 2d array as a paramater


laclac01@yahoo.com wrote:
[color=blue]
> Is there a way to pass a 2d array to a function in c++ with out having
> to specifiy the number of elements in the array. Here is an example
>
>
Expand|Select|Wrap|Line Numbers
  1. > #include<iostream>
  2. > using namespace std;
  3. >
  4. > int main()
  5. > {
  6. >    int array[10][10];
  7. >    fill(array,rows,cols);
  8. >    return 0;
  9. >
  10. > }
  11. > void fill(int array[10][10], rows,cols)
  12. > {
  13. >    int i, j;
  14. >
  15. >    for(i=0;i<10;i++)
  16. >    for(j=0;j<10;j++)
  17. >    array[i][j]=0;
  18. > }
> array needs to have the [10][10] or at least
> [][10]. is there a way i can make it so it
> only needs [][]?[/color]

You could consider

a) packaging your matrix into a class.
b) turning that class into a template.

a) has the advantage that it separates the implementation from the
interface.

b) makes the whole thing more generic.

E.g.:

template < typename arithmetic_type, unsigned long ROWS, unsigned long COLS[color=blue]
>[/color]
class matrix {
public:

typedef arithmetic_type value_type;

static
const unsigned long rows = ROWS;

static
const unsigned long cols = COLS;

private:

value_type data [ rows ][cols];

public:

value_type & operator() ( unsigned long row_index,
unsigned long col_index ) {
return( data[row_index][col_index] );
}

value_type const & operator() ( unsigned long row_index,
unsigned long col_index ) const {
return( data[row_index][col_index] );
}


};// matrix

template < typename arithmetic_type, unsigned long ROWS, unsigned long COLS[color=blue]
>[/color]
void fill_matrix ( matrix< arithmetic_type, ROWS, COLS > & matr ) {
for ( unsigned long r = 0; r < ROWS; ++r ) {
for ( unsigned long c = 0; c < COLS; ++c ) {
matr(r,c) = 0;
}
}
}

typedef matrix< float, 3001, 204 > MediumMatrix;

int main ( void ) {
MediumMatrix mat;
fill_matrix( mat );
}


Note in particular, how template resolution allows you to not explicitly
pass the dimensions of mat to the function fill_matrix(). The static type
of the object mat is all that the compiler needs to choose the right
dimensions.


Best

Kai-Uwe Bux
David Hilsee
Guest
 
Posts: n/a
#4: Aug 27 '05

re: passing a 2d array as a paramater


<laclac01@yahoo.com> wrote in message
news:1125144425.307528.261480@f14g2000cwb.googlegr oups.com...[color=blue]
> Is there a way to pass a 2d array to a function in c++ with out having
> to specifiy the number of elements in the array. Here is an example
>
>
Expand|Select|Wrap|Line Numbers
  1. > #include<iostream>
  2. > using namespace std;
  3. >
  4. > int main()
  5. > {
  6. >    int array[10][10];
  7. >    fill(array,rows,cols);
  8. >    return 0;
  9. >
  10. > }
  11. > void fill(int array[10][10], rows,cols)
  12. > {
  13. >    int i, j;
  14. >
  15. >    for(i=0;i<10;i++)
  16. >    for(j=0;j<10;j++)
  17. >    array[i][j]=0;
  18. > }
> array needs to have the [10][10] or at least
> [][10]. is there a way i can make it so it
> only needs [][]?[/color]

One solution is given in the C FAQ here:

http://www.eskimo.com/~scs/C-faq/q6.19.html

This solution is covered in Stroustrup's TC++PL.

--
David Hilsee


Frank Chang
Guest
 
Posts: n/a
#5: Aug 27 '05

re: passing a 2d array as a paramater


Kai_Uwe Bux, The disadvantage of having to write a new class for 2D,
3D, 4D etc matrices can be ameriolated by using the boost:multi_array
template class:

int rows(1000);
int columns(1000);

//num_dimensions = 2
boost::multi_array< int , 2 > foo( boost::extents[rows][columns] ); //2
= two dimentions

and your fill function fill(foo&) body might look like

for ( unsigned long r = 0; r < ROWS; ++r ) {
for ( unsigned long c = 0; c < COLS; ++c ) {
foo[r][c] = 0.0;
}
}

Kai-Uwe Bux
Guest
 
Posts: n/a
#6: Aug 27 '05

re: passing a 2d array as a paramater


Frank Chang wrote:
[color=blue]
> Kai_Uwe Bux, The disadvantage of having to write a new class for 2D,
> 3D, 4D etc matrices can be ameriolated by using the boost:multi_array
> template class:[/color]

Frank Chang,

a) we do not know if the OP wants to go into 3D and 4D.

b) in any case, one sure does not "have to write a new class". As was
pointed out to the OP in another thread already, there are libraries for
linear algebras, even free ones. You pointed toward the Boost matrix
library yourself, if I recall correctly. However, for some reason the OP
does not seem to be at ease with the idea of using third party libraries.

Thus, I was merely pointing out that there is an advantage in encapsulation.
[color=blue]
>
> int rows(1000);
> int columns(1000);
>
> //num_dimensions = 2
> boost::multi_array< int , 2 > foo( boost::extents[rows][columns] ); //2
> = two dimentions
>
> and your fill function fill(foo&) body might look like
>
> for ( unsigned long r = 0; r < ROWS; ++r ) {
> for ( unsigned long c = 0; c < COLS; ++c ) {
> foo[r][c] = 0.0;
> }
> }[/color]

Yup, that's cool. Now, sell that to the OP -- need to convince me.


Best

Kai-Uwe Bux
Frank Chang
Guest
 
Posts: n/a
#7: Aug 27 '05

re: passing a 2d array as a paramater


Kai-Uwe Bux, I understand that the original poster's question dealt
with 2D arrays. But, in engineering and science C++ applications, one
sometimes needs to abstract solutions to N dimensional solutions. That
way, the solution is more extensible to other problems.

I know we talked about the boost::Matrix class, which is only a 2
dimensional matrix, before but the OP in this case still wants to deal
with two dimensional arrays rather than matrix classes using the
vector-of-vector paridigm which you developed. What can we do? The OP
states:
"Is there a way to pass a 2d array to a function in c++ with out having

to specifiy the number of elements in the array"

In conclusion, your solution appears to be correct for the OP's problem
and I am not going to dispute you on that. Thank you for your reply.

Aleksey Loginov
Guest
 
Posts: n/a
#8: Aug 29 '05

re: passing a 2d array as a paramater



laclac01@yahoo.com wrote:[color=blue]
> Is there a way to pass a 2d array to a function in c++ with out having
> to specifiy the number of elements in the array. Here is an example
>
>
Expand|Select|Wrap|Line Numbers
  1. > #include<iostream>
  2. > using namespace std;
  3. >
  4. > int main()
  5. > {
  6. >    int array[10][10];
  7. >    fill(array,rows,cols);
  8. >    return 0;
  9. >
  10. > }
  11. > void fill(int array[10][10], rows,cols)
  12. > {
  13. >    int i, j;
  14. >
  15. >    for(i=0;i<10;i++)
  16. >    for(j=0;j<10;j++)
  17. >    array[i][j]=0;
  18. > }
> array needs to have the [10][10] or at least
> [][10]. is there a way i can make it so it
> only needs [][]?[/color]

maybe

template<unsigned rows,unsigned cols>
void fill(int (&array)[rows][cols])

?

Frank Chang
Guest
 
Posts: n/a
#9: Aug 29 '05

re: passing a 2d array as a paramater


Aleksey, You could make your template even more generic;

template<typename T, unsigned rows,unsigned cols>
void fill(T (&array)[rows][cols])
{
int i, j;

for(i=0;i<10;i++)
for(j=0;j<10;j++)
array[i][j]=0;
}


int _tmain(int argc, _TCHAR* argv[])
{
Complex array[10][10];
fill<Complex>(array);
}

Dave Rahardja
Guest
 
Posts: n/a
#10: Aug 30 '05

re: passing a 2d array as a paramater


On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <FrankChang91@gmail.com> wrote:
[color=blue]
>Aleksey, You could make your template even more generic;
>
>template<typename T, unsigned rows,unsigned cols>
>void fill(T (&array)[rows][cols])
>{
> int i, j;
>
> for(i=0;i<10;i++)
> for(j=0;j<10;j++)
> array[i][j]=0;
>}
>
>
>int _tmain(int argc, _TCHAR* argv[])
>{
> Complex array[10][10];
> fill<Complex>(array);
>}[/color]

Or even better,

#include <vector>

using namespace std;

typedef vector<vector<int>> vvi_t;

void fill(vvi_t& array)
{
array.reserve(10);
for (int i = 0; i < 10; ++i) {
array[i].reserve(10);
for (int j = 0; j < 10; ++i) {
array[i][j] = 0;
}
}
}

....
David Hilsee
Guest
 
Posts: n/a
#11: Aug 30 '05

re: passing a 2d array as a paramater


"Dave Rahardja" <ask@me.com> wrote in message
news:0jb7h115bpb7aoo67bgi1kkgo3f9391ppr@4ax.com...[color=blue]
> On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <FrankChang91@gmail.com>[/color]
wrote:[color=blue]
>[color=green]
> >Aleksey, You could make your template even more generic;
> >
> >template<typename T, unsigned rows,unsigned cols>
> >void fill(T (&array)[rows][cols])
> >{
> > int i, j;
> >
> > for(i=0;i<10;i++)
> > for(j=0;j<10;j++)
> > array[i][j]=0;
> >}
> >
> >
> >int _tmain(int argc, _TCHAR* argv[])
> >{
> > Complex array[10][10];
> > fill<Complex>(array);
> >}[/color]
>
> Or even better,
>
> #include <vector>
>
> using namespace std;
>
> typedef vector<vector<int>> vvi_t;
>
> void fill(vvi_t& array)
> {
> array.reserve(10);
> for (int i = 0; i < 10; ++i) {
> array[i].reserve(10);
> for (int j = 0; j < 10; ++i) {
> array[i][j] = 0;
> }
> }
> }[/color]

While std::vector is generally better and more powerful than an array, this
code isn't as generic as Frank's and also has bugs because it uses reserve()
instead of resize() (the assignment to zero would be unnecessary with
resize() as well). It also does not allow the calling code to provide the
dimensions, but that's a nitpick.

--
David Hilsee


Aleksey Loginov
Guest
 
Posts: n/a
#12: Aug 30 '05

re: passing a 2d array as a paramater



Frank Chang wrote:[color=blue]
> Aleksey, You could make your template even more generic;[/color]

:) i know :)
add sugar, if you like...
[color=blue]
>
> template<typename T, unsigned rows,unsigned cols>
> void fill(T (&array)[rows][cols])
> {
> }
>
>
> int _tmain(int argc, _TCHAR* argv[])[/color]

what is _tmain()? :)
[color=blue]
> {
> Complex array[10][10];
> fill<Complex>(array);[/color]

complex doesn't needed here
[color=blue]
> }[/color]

Dave Rahardja
Guest
 
Posts: n/a
#13: Aug 30 '05

re: passing a 2d array as a paramater


On Mon, 29 Aug 2005 21:57:42 -0400, "David Hilsee" <davidhilseenews@yahoo.com>
wrote:
[color=blue]
>"Dave Rahardja" <ask@me.com> wrote in message
>news:0jb7h115bpb7aoo67bgi1kkgo3f9391ppr@4ax.com.. .[color=green]
>> On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <FrankChang91@gmail.com>[/color]
>wrote:[color=green]
>>[color=darkred]
>> >Aleksey, You could make your template even more generic;
>> >
>> >template<typename T, unsigned rows,unsigned cols>
>> >void fill(T (&array)[rows][cols])
>> >{
>> > int i, j;
>> >
>> > for(i=0;i<10;i++)
>> > for(j=0;j<10;j++)
>> > array[i][j]=0;
>> >}
>> >
>> >
>> >int _tmain(int argc, _TCHAR* argv[])
>> >{
>> > Complex array[10][10];
>> > fill<Complex>(array);
>> >}[/color]
>>
>> Or even better,
>>
>> #include <vector>
>>
>> using namespace std;
>>
>> typedef vector<vector<int>> vvi_t;
>>
>> void fill(vvi_t& array)
>> {
>> array.reserve(10);
>> for (int i = 0; i < 10; ++i) {
>> array[i].reserve(10);
>> for (int j = 0; j < 10; ++i) {
>> array[i][j] = 0;
>> }
>> }
>> }[/color]
>
>While std::vector is generally better and more powerful than an array, this
>code isn't as generic as Frank's and also has bugs because it uses reserve()
>instead of resize() (the assignment to zero would be unnecessary with
>resize() as well). It also does not allow the calling code to provide the
>dimensions, but that's a nitpick.[/color]

Oops, you are correct about reserve(). It should have been

if (array.size() < 10) array.resize(10);

or something like that.

This may be a moot point, but I thought the OP wanted to fill the first 10
elements of the array (in both dimensions) with zeros, regardless of the
actual size of the array. Anyway, add features to taste, I suppose.
E. Robert Tisdale
Guest
 
Posts: n/a
#14: Aug 30 '05

re: passing a 2d array as a paramater


laclac01@yahoo.com wrote:
[color=blue]
> Is there a way to pass a 2d array to a function in c++ with out having
> to specifiy the number of elements in the array. Here is an example[/color]
[color=blue]
> cat fill.c[/color]
#include <stdlib.h>

void
fill(size_t rows, size_t cols, int array[rows][cols], int k) {
for (size_t i = 0; i < rows; ++i)
for (size_t j = 0; j < cols; ++j)
array[i][j] = k;
}
[color=blue]
> gcc -Wall -std=c99 -pedantic -c fill.c
> cat main.cc[/color]
#include<iostream>

extern "C" {
void fill(size_t, size_t, int*, int);
}

int main(int argc, char* argv) {
const size_t rows = 10;
const size_t cols = 10;
int array[rows][cols];

fill(rows, cols, &array[0][0], 0);
for (size_t i = 0; i < rows; ++i) {
for (size_t j = 0; j < cols; ++j)
std::cout << ' ' << array[i][j];
std::cout << std::endl;
}

return 0;
}
[color=blue]
> g++ -Wall -ansi -pedantic -o main main.cc fill.o
> ./main[/color]
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Eventually, C++ will adopt C99 variable size arrays
and you will be able to compile fill with your C++ compiler.
Frank Chang
Guest
 
Posts: n/a
#15: Aug 31 '05

re: passing a 2d array as a paramater


Aleksey, _tmain() is the MSVC 7.1 version of the main function
automatically generated when you create a new MSVC 7.1 program.
Regarding complex, the reason I put it there was because the original
poster has been talking about a two dimensional array of complex
numbers in other posts and I was just trying to show the syntatic sugar
..
The other issue I would like to raise is this:
[color=blue][color=green]
>>template<unsigned rows,unsigned cols>
>>void fill(int (&array)[rows][cols])[/color][/color]

What would you think about using an non-template fill function without
specifying template arguments for the number of rows and columns? For
example,

typedef boost::multi_array<int,2> marray; // 2 dimensional

void fill_matrix(marray& matr)
{
// we can deduce the rows and columns of the matrix matr
// by using boost multi_array member functions instead
// of template arguments.

multi_array< int, 2 >::iterator it = matr.begin();
// use iterator it to fill matr with 0's
}


int _tmain(int argc, _TCHAR* argv[])
{
using namespace boost;
using namespace std;

boost::multi_array< int , 2 > matr(boost::extents[10][12]); //10
rows, 12 cols
fill_matrix(matr);
}

If this program runs okay for you, then we are no longer debating about
syntatic sugar. Please take a look at www.boost.org for more
information if you should wish. Thank you.

Aleksey Loginov
Guest
 
Posts: n/a
#16: Aug 31 '05

re: passing a 2d array as a paramater



Frank Chang wrote:[color=blue]
> Aleksey, _tmain() is the MSVC 7.1 version of the main function
> automatically generated when you create a new MSVC 7.1 program.[/color]

non standard
[color=blue]
> Regarding complex, the reason I put it there was because the original
> poster has been talking about a two dimensional array of complex
> numbers in other posts and I was just trying to show the syntatic sugar.[/color]

i mean that you don't need to type explicit fintion name like
"fill<complex>"...
[color=blue]
> The other issue I would like to raise is this:
>[color=green][color=darkred]
> >>template<unsigned rows,unsigned cols>
> >>void fill(int (&array)[rows][cols])[/color][/color]
>[/color]

here i just show OP way to pass multidimensional array to the function.
[color=blue]
> What would you think about using an non-template fill function without
> specifying template arguments for the number of rows and columns? For
> example,
>[/color]

for small programs arrays will enough, i think
[color=blue]
>
> typedef boost::multi_array<int,2> marray; // 2 dimensional
>
> void fill_matrix(marray& matr)
> {
> // we can deduce the rows and columns of the matrix matr
> // by using boost multi_array member functions instead
> // of template arguments.
>
> multi_array< int, 2 >::iterator it = matr.begin();
> // use iterator it to fill matr with 0's
> }
>
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> using namespace boost;
> using namespace std;
>
> boost::multi_array< int , 2 > matr(boost::extents[10][12]); //10
> rows, 12 cols
> fill_matrix(matr);
> }
>
> If this program runs okay for you, then we are no longer debating about
> syntatic sugar. Please take a look at www.boost.org for more
> information if you should wish. Thank you.[/color]

prefer boost::matrix

Frank Chang
Guest
 
Posts: n/a
#17: Aug 31 '05

re: passing a 2d array as a paramater


Aleksey, Yes MSVC7.1 _tmain() is not standard C++, but MSVC 7.1 is a
huge step toward conforming with standard C++. MSVC8.0 promises to be
even better in this respect.
fill<complex> vs f<> . First , it is easier to read. Second, it
absolutely guarantees that the user must pass a complex 2D array to
fill() or you will get a compiler error: ""'fill' : invalid template
argument for 'T', missing template argument list on class template"

Finally. I think the issue about boost::multiarray versus
boost::matrix has very little to do with the size of the program: R.
Garcia, possibly from www.boost.org, writes:

"First, bear in mind that there is a difference between a general
n-dimensional array library and a linear algebra library. While a
linear algebra library will tend to use two dimensional matrices to
represent linear transformations, some algorithms can make use of
matrix-free representations, where the matrix form of the
transformation never exists. In addition, operation semantics
(specifically operator*()) can differ depending on use."

My belief is that for this problem, boost_multi_array is more
appropriate.
Aleksey, what is view on this issue? Thank you.

Aleksey Loginov
Guest
 
Posts: n/a
#18: Sep 1 '05

re: passing a 2d array as a paramater



Frank Chang wrote:[color=blue]
>
> Finally. I think the issue about boost::multiarray versus
> boost::matrix has very little to do with the size of the program: R.
> Garcia, possibly from www.boost.org, writes:
>
> "First, bear in mind that there is a difference between a general
> n-dimensional array library and a linear algebra library. While a
> linear algebra library will tend to use two dimensional matrices to
> represent linear transformations, some algorithms can make use of
> matrix-free representations, where the matrix form of the
> transformation never exists. In addition, operation semantics
> (specifically operator*()) can differ depending on use."
>
> My belief is that for this problem, boost_multi_array is more
> appropriate.[/color]

actually, i dont remember source problem :)
[color=blue]
> Aleksey, what is view on this issue?[/color]

i use c++ for pleasure and dont have big practical experience.
arrays and std::vector enough for me :)
[color=blue]
> Thank you.[/color]

at any time.

Frank Chang
Guest
 
Posts: n/a
#19: Sep 1 '05

re: passing a 2d array as a paramater


Aleksey, Please keep contributing your ideas in this newsgroup. Your
ideas are quite good. I have to admit this 2d array/matrix subject is
getting a bit repititive. Без перевода.
Closed Thread