473,385 Members | 1,888 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

passing a 2d array as a paramater

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 [][]?

Aug 27 '05 #1
18 18607
la******@yahoo.com wrote:
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.  int main()
  4.  {
  5.     int array[10][10];
  6.     fill(array,rows,cols);
  7.     return 0;
  8.  }
  9.  void fill(int array[10][10], rows,cols)
  10.  {
  11.     int i, j;
  12.     for(i=0;i<10;i++)
  13.     for(j=0;j<10;j++)
  14.     array[i][j]=0;
  15.  }
  16.  
array needs to have the [10][10] or at least
[][10]. is there a way i can make it so it
only needs [][]?


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
Aug 27 '05 #2
la******@yahoo.com wrote:
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.  int main()
  4.  {
  5.     int array[10][10];
  6.     fill(array,rows,cols);
  7.     return 0;
  8.  }
  9.  void fill(int array[10][10], rows,cols)
  10.  {
  11.     int i, j;
  12.     for(i=0;i<10;i++)
  13.     for(j=0;j<10;j++)
  14.     array[i][j]=0;
  15.  }
  16.  
array needs to have the [10][10] or at least
[][10]. is there a way i can make it so it
only needs [][]?
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 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

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
Aug 27 '05 #3
<la******@yahoo.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
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.  int main()
  4.  {
  5.     int array[10][10];
  6.     fill(array,rows,cols);
  7.     return 0;
  8.  }
  9.  void fill(int array[10][10], rows,cols)
  10.  {
  11.     int i, j;
  12.     for(i=0;i<10;i++)
  13.     for(j=0;j<10;j++)
  14.     array[i][j]=0;
  15.  }
  16.  
array needs to have the [10][10] or at least
[][10]. is there a way i can make it so it
only needs [][]?


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
Aug 27 '05 #4
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;
}
}

Aug 27 '05 #5
Frank Chang wrote:
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:
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.

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;
}
}


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

Kai-Uwe Bux
Aug 27 '05 #6
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.

Aug 27 '05 #7

la******@yahoo.com wrote:
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.  int main()
  4.  {
  5.     int array[10][10];
  6.     fill(array,rows,cols);
  7.     return 0;
  8.  }
  9.  void fill(int array[10][10], rows,cols)
  10.  {
  11.     int i, j;
  12.     for(i=0;i<10;i++)
  13.     for(j=0;j<10;j++)
  14.     array[i][j]=0;
  15.  }
  16.  
array needs to have the [10][10] or at least
[][10]. is there a way i can make it so it
only needs [][]?


maybe

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

?

Aug 29 '05 #8
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);
}

Aug 29 '05 #9
On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <Fr**********@gmail.com> wrote:
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);
}


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;
}
}
}

....
Aug 30 '05 #10
"Dave Rahardja" <as*@me.com> wrote in message
news:0j********************************@4ax.com...
On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <Fr**********@gmail.com> wrote:
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);
}


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;
}
}
}


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
Aug 30 '05 #11

Frank Chang wrote:
Aleksey, You could make your template even more generic;
:) i know :)
add sugar, if you like...

template<typename T, unsigned rows,unsigned cols>
void fill(T (&array)[rows][cols])
{
}
int _tmain(int argc, _TCHAR* argv[])
what is _tmain()? :)
{
Complex array[10][10];
fill<Complex>(array);
complex doesn't needed here
}


Aug 30 '05 #12
On Mon, 29 Aug 2005 21:57:42 -0400, "David Hilsee" <da*************@yahoo.com>
wrote:
"Dave Rahardja" <as*@me.com> wrote in message
news:0j********************************@4ax.com.. .
On 29 Aug 2005 03:53:29 -0700, "Frank Chang" <Fr**********@gmail.com>

wrote:
>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);
>}


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;
}
}
}


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.


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.
Aug 30 '05 #13
la******@yahoo.com wrote:
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 cat fill.c #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;
}
gcc -Wall -std=c99 -pedantic -c fill.c
cat main.cc #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;
}
g++ -Wall -ansi -pedantic -o main main.cc fill.o
./main

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.
Aug 30 '05 #14
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:
template<unsigned rows,unsigned cols>
void fill(int (&array)[rows][cols])


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.

Aug 31 '05 #15

Frank Chang wrote:
Aleksey, _tmain() is the MSVC 7.1 version of the main function
automatically generated when you create a new MSVC 7.1 program.
non standard
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.
i mean that you don't need to type explicit fintion name like
"fill<complex>"...
The other issue I would like to raise is this:
template<unsigned rows,unsigned cols>
void fill(int (&array)[rows][cols])


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

for small programs arrays will enough, i think

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.


prefer boost::matrix

Aug 31 '05 #16
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.

Aug 31 '05 #17

Frank Chang wrote:

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.
actually, i dont remember source problem :)
Aleksey, what is view on this issue?
i use c++ for pleasure and dont have big practical experience.
arrays and std::vector enough for me :)
Thank you.


at any time.

Sep 1 '05 #18
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. Без перевода.
Sep 1 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: JW | last post by:
Hi, Below is a description of what I would like to do. Would someone tell me if it is possible and if so, how? I have an array (presumably 'large') that is mallocced in a C function and its...
1
by: lolomgwtf | last post by:
I have a managed C++ method that wraps unmanaged code and creates a managed object holding data retrieved form an unmanged one. I want create an instance of this managed class in C#, pass it to...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
1
by: Tércio | last post by:
Hi there! I'm having this problem and I'm not finding the solution for this. I have a COM (VB6), that receives in a method a variant paramater. But this parameter is treated internally as a...
4
by: Mike Dinnis | last post by:
Hi, I've been working through a number of turorials to try to learn more about retrieving data from a SQL database. I think i've mastered techniques where i create a sql string in the page and...
11
by: John Pass | last post by:
Hi, In the attached example, I do understand that the references are not changed if an array is passed by Val. What I do not understand is the result of line 99 (If one can find this by line...
1
by: Scott Izu | last post by:
'Method 1 Dim Form1 As Form = Activator.CreateInstance(Of frmContractEdit)() Form1.Show() 'Method 2 Dim Form2Type As Type = GetType(frmContractEdit) MsgBox(Form2Type.AssemblyQualifiedName)...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.