开发者

C++ passing Dynamically-sized 2D Array to function

开发者 https://www.devze.com 2023-01-30 04:22 出处:网络
I\'m trying to figure out how to pass 2D array, which is constructed dynamically to a function. I know that number of columns must be specified, but it my case it depends on user input.

I'm trying to figure out how to pass 2D array, which is constructed dynamically to a function. I know that number of columns must be specified, but it my case it depends on user input.

Are there any workarounds?

Example:

// Some function
void function(matrix[i][j]) {
// do stuff
}
// Main function
int N;
cout << "Size: ";
cin >> N;

int matrix[N][N];

for (int i=0;i<N;i++) { //开发者_StackOverflow社区 
 for (int j=0;j<N;j++) { 
  cin >> matrix[N][N];
 }
}

sort(matrix);

You get the idea :)


If you're on C++, the reasonable options are to:

  • use boost::multi_array (recommended), or
  • make your own 2D array class. Well, you don't have to, but encapsulating 2D array logic in a class is useful and makes the code clean.

Manual 2D array indexing would look like this:

void func(int* arrayData, int arrayWidth) {
    // element (x,y) is under arrayData[x + y*arrayWidth]
}

But seriously, either wrap this with a class or enjoy that Boost already has that class ready for you. Indexing this manually is tiresome and makes the code more unclean and error-prone.


edit

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html says that C99 has one more solution for you:

void func(int len, int array[len][len]) {
   // notice how the first parameter is used in the definition of second parameter
}

Should also work in C++ compilers, but I haven't ever used this approach.


In C++, the compiler can figure out the size, since it's part of the type. Won't work with dynamically sized matrices though.

template<size_t N, size_t M>
void function(int (&matrix)[N][M])
{
  // do stuff
}

EDIT: In GCC only, which is required for your code defining the array, you can pass variable-length arrays directly:

void func(int N, int matrix[N][N])
{
  //do stuff
}

See the gcc documentation


/*******************************************************\
*                                                       *
* I am not claiming to be an expert, but I think I know *
* a solution to this one. Try using a Vector Container  *
* instead of an array. Here is an example below:        *
*                                                       *
* Load the target file with a Multiplication Table      *
*                                                       *
*                                                       *
\*******************************************************/

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


std::string user_file;
int user_size = 2;
void array_maker(int user_size, std::string user_file);

int main () {
  std::cout << "Enter the name of the file for your data: ";
  std::cin >> user_file;
  std::cout << std::endl;
  std::cout << "Enter the size for your Multiplication Table: ";
  std::cin >> user_size;

  // Create the users Multiplication data
     array_maker(user_size, user_file);

  return (0);
}

void array_maker(int user_size, std::string user_file)
{
  // Open file to write data & add it to end of file
  std::ofstream target_file(user_file,std::ios::out | std::ios::app);

  // Declare the vector to use as a runtime sized array
  std::vector<std::vector<int>> main_array;

  // Initialize the size of the vector array
  main_array.resize(user_size+1); // Outer Dimension
  for (int i=0; i <= user_size; ++i) // Inner Dimension
  {
    main_array[i].resize(user_size+1);
  }

  for (int i=0; i<=user_size; ++i) 
  {
    for (int j=0; j<=user_size; ++j)
    {
      main_array[i][j] = i * j;
      // output line to current record in file
      target_file << i << "*" 
              << j << "=" 
              << main_array[i][j] << " "
              << "EOR"   // End of Record 
              << std::endl;

    } // Close Inner For
  } // Close Outer For
  // close file
  target_file.close();

} // Close array_maker function


You can do void function (int** __matrix, int32_t __row, int32_t __column) __row - max rows __column - max columns.

You will need those params to find out the limits of the array.


Just add another parametrs to your function - row_number and column_number. Arrays are not object in C++ so they don't store any additional information about themselfs.


If you pass in the array identifier (as a pointer to a pointer) you will need to use pointer arithmetic:

void function(int** matrix, int num_rows, int num_cols) {
    Assert(matrix!=NULL && *matrix!=NULL && num_rows>0 && num_cols>0);

    for(int i=0; i<num_rows; i++) {
        for(int j=0; j<num_cols; j++) {
            // cannot index using [] like matrix[i][j]
            // use pointer arithmetic instead like:
            // *(matrix + i*num_cols + j)

        }
    }
}


to pass multi dimensional arays into method the compiler needs to know the depth of each field, so one solution is to use templates and call method in a normal way and the compiler will guess the size of each field.

template <size_t m>
void method(int M[][m])
{
    for(int i=0; i<m; ++i)
        for(int j=0; j<m; ++j)
        {
            // do funny stuff with M[i][j]
        }
}

int main()
{
    int M[5][5] = { {1,0,1,1,0}, {0,1,1,1,0}, {1,1,1,1,1}, {1,0,1,1,1}, {1,1,1,1,1} };
    method(M);
    // also you can call with method<5>(M)
    // if you have different sizes for each dimension try passing them in args
    return 0;
}


int r, c
int *matrix = new int[r,c];
for (int i = 0; i < r; i++)
    {
        /*cout << "Enter data" << endl;*/
        for (int j = 0; j < c; j++)
        {
            cin >> matrix[i,j];

        }
    }


void function(int &matrix[][] )

0

精彩评论

暂无评论...
验证码 换一张
取 消