как передать массивы и вернуть значения массивов 2-й матрицы? - PullRequest
1 голос
/ 20 ноября 2010

звонок с основного

matrix_multiplication(arrayA,arrayB,row1,col1,col2);

определение функции

float matrix__multiplication(float **arrayA,float **arrayB,int row1,int col1,int col2)
{
float result[row1][col2];
result[][]=....

return result;
}

Я хотел знать, как передавать 2d-массивы в вызов функции, как получить в определении функции а как вернуть матрицу результата?

Ответы [ 3 ]

1 голос
/ 20 ноября 2010

Использование необработанных указателей для ваших массивов, как это больше в стиле C, чем в C ++.Использовать вектор вектора (индексирование все еще очень эффективно).

size_t rows(5);
size_t columns(15);
vector<float> row(columns);
vector<vector<float>> matrix(rows, row);
matrix[0][0] = 0.1f;

Еще лучше обернуть базовое хранилище в классе Matrix, который реализует необходимые матричные операции, хранит и применяет измерения, обеспечивает совместимость матриц для умноженияи т. д.

class Matrix
{ 
public:
  Matrix(const int _rows, const int _cols) : rows(_rows), cols(_cols)
  {
  }

  Matrix Multiply(const Matrix& rhs);

private:
  vector<vector<float>> storage;
  size_t rows;
  size_t cols;
};

Matrix Matrix::multiply(const Matrix& rhs)
{
  Matrix result(*this, rhs);   // construct matrix of right dimensions
  // multiply the operands
  return result;     // modern compilers do not copy construct the result
}

Если ваши требования к матрице сложны, вы можете рассмотреть такую ​​библиотеку, как Boost.UBlas вместо своей собственной.Это шаблонный код и поддерживает специализации для разреженных, диагональных и других распространенных типов матриц.

0 голосов
/ 20 ноября 2010

То, что вы написали, не является допустимым кодом C ++. Чтобы инициализировать result для правильного размера, row и col должны быть константами времени компиляции, которыми они не являются. Вы либо возвращаете float** из своей функции, которую вы назначаете локально, либо (лучше) вы передаете предварительно выделенный float** result в качестве другого параметра вашей функции (которую вы все равно можете вернуть). Однако, как правило, вы не будете использовать двумерные массивы для хранения матриц, вы скорее определите линейное хранилище для матрицы в одномерном массиве и определите соответствующие методы доступа.

float** matrix__multiplication(float **arrayA,float **arrayB,float **result, int row1,int col1,int col2)  
{  
 // ...
 return result;  
}

// caller needs to allocate (and de-allocate) space (see the mess?):
result = new float* [row1];
std::for_each(result, result + row1, [col2] (float*& pCurr) -> void {
 pCurr = new float[col2];
});  

result = matrix_multiplication(a, b, result, row1, col1, col2);
0 голосов
/ 20 ноября 2010

Я бы сделал это примерно так, передав ссылку на массив 2D (фактически D1 ​​X D2) любого типа. Это также позволит избежать необходимости возвращать что-либо обратно.

Если функции необходимо изменить аргумент входного массива, удалите const.

void f( T const (&r)[D1][D2] ){}

int main() { 
   float fbuf[10][3];
   f(fbuf);
} 

Если вы все же настаиваете на том, чтобы функция возвращала двумерный массив, вы можете сделать что-то вроде этого:

template<class T, size_t D1, size_t D2>
T (&f( T const (&r)[D1][D2] ))[D1][D2]{
   T temp[D1][D2];
   return temp;
}

int main() { 
   float fbuf[10][3];
   f(fbuf);
} 
...