Passing 2-Dimensional Array to Function

Hi everyone,

I'm having an issue with 2-dimensional arrays. I am trying to create a function prototype that will allow me to manipulate an array argument that is either one-dimensional or two-dimensional. For example, here's the code I'm trying to achieve (note: this does not compile):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

void manipulate_arrays(double *myarray, int rows, int cols)
{
// Note: the rows and cols are parameters even if it's a one dimensional array
// I would like to be able to use a value of 0 for cols if it's a one dimensional array

// Print/Manipulate values:


if(cols == 0) // This is a one dimensional array
{
    // Notice how I am using '0' in the second array dimension even though this is a one-dimensional array. Is this even possible?
    cout << "one dimensional array " << endl;
    cout << "index 0: " << myarray[0][0] << endl;  
    cout << "index 1: " << myarray[1][0] << endl;
    cout << "index 2: " << myarray[2][0] << endl;
}
else
{
    cout << "two dimensional array" << endl;
    cout << "index 0,0 : " << myarray[0][0] << endl;
    cout << "index 0,1 : " << myarray[0][1] << endl;
    cout << "index 0,2 : " << myarray[0][2] << endl;
    cout << "index 0,3 : " << myarray[0][3] << endl;
    cout << "index 0,4 : " << myarray[0][4] << endl;
    cout << "index 1,0 : " << myarray[1][0] << endl;
    cout << "index 1,1 : " << myarray[1][1] << endl;
    cout << "index 1,2 : " << myarray[1][2] << endl;
    cout << "index 1,3 : " << myarray[1][3] << endl;
    cout << "index 1,4 : " << myarray[1][4] << endl;
    // same for rows 2, 3
}

}

int main()
{
    double array_1[3];
    double array_2[4][5];

    // initialize arrays with values...

    manipulate_arrays(array_1, 3, 0);
    manipulate_arrays(array_2, 4, 5);

    return 1;[/center]
}


The code above does not seem to compile. How can I declare the prototype to allow this?

Thanks-
Last edited on
Here you go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;

// This function takes things the C way
void print_array( double* xs, int cols, int rows = 1 )
  {
  for (int r = 0; r < rows; r++)
    {
    for (int c = 0; c < cols; c++)
      {
      cout << xs[ (r * cols) + c ] << " ";
      }
    cout << "\n";
    }
  }

// These overloads do things the C++ way
// (but we simply pass along to the C way)
template <int C>
inline
void print_array( double (&xs)[ C ] )
  {
  print_array( (double*)xs, C );
  }

template <int C, int R>
inline
void print_array( double (&xs)[ R ][ C ] )
  {
  print_array( (double*)xs, C, R );
  }

int main()
  {
  double d1     [ 5 ] =  { 1, 2, 3, 4, 5 };
  double d2[ 2 ][ 5 ] = {{ 9, 8, 7, 6, 5 },
                         { 4, 3, 2, 1, 0 }};

  // The C way
  cout << "d1\n";  print_array( (double*)d1, 5 );
  cout << "d2\n";  print_array( (double*)d2, 5, 2 );

  cout << "\n";

  // The C++ way
  cout << "d1\n";  print_array( d1 );
  cout << "d2\n";  print_array( d2 );

  return 0;
  }

Notice that you cannot have zero for a dimension. A one dimensional array is, essentially, a two dimensional array where one of the dimensions has a cardinality of one.

Hope this helps.
Thanks Duoas! Very helpful.

So it seems like once the array enters print_array, the data/pointer (*xs) is flattened out in a one dimensional array. Is it possible to access a pointer such as (*xs) using 2 brackets such as [][] ?
(Just trying to find a way to make it even more explicit, haha) If not, this will suffice!

Anyhow, thanks a lot!
No, not unless you provide the exact type of the array for all dimensions (except the first) for the argument.

The C++ templated solution does just that... otherwise the array is always "flattened". Actual multidimensional C/C++ arrays are actually stored linearly -- the multidimensional aspect is syntactic sugar for the programmer.

You might benefit from reading about arrays here:
http://www.cplusplus.com/doc/tutorial/arrays/


Inside the C-style function, you might make use of another simple function to help you access the elements of your multidimensional arrays:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Here's a little helper function
// (Keep in mind that it does not prevent out-of-range row indexes)
inline
double& index( double* xs, int cols, int row, int col )
  {
  return xs[ (row * cols) + col ];
  }

// This function takes things the C way
void print_array( double* xs, int cols, int rows = 1 )
  {
  for (int r = 0; r < rows; r++)
    {
    for (int c = 0; c < cols; c++)
      {
      cout << index( xs, cols, r, c ) << " ";
      }
    cout << "\n";
    }
  }

Beyond that, it is a waste of time to make it look pretty using those nice [] operators... Alas.

Hope this helps.
Topic archived. No new replies allowed.