【问题标题】:Populate a 2d array after initialization in c++在 C++ 中初始化后填充二维数组
【发布时间】:2020-12-03 17:27:25
【问题描述】:

我需要在 c++ 中的函数中填充一个二维数组(表示矩阵)。

函数如下所示:

double** makeMatrix (const char c, double a) {
    double matrix[3][3];
    
    switch (c) {
        case 'x' :
            matrix = {{1, 0, 0), {0, cos(a), -sin(a)}, {0, sin(a), cos(a)}};
            break;
        case 'y' :
            matrix = {{cos(a), 0, sin(a)}, {0, 1, 0}, {-sin(a), 0, cos(a)}};
            break;
        case 'z' :
            matrix = {{cos(a), -sin(a), 0}, {sin(a), cos(a)}, {0, 0, 1}};
            break;
    }
    return matrix;
}

不用说,这个功能不起作用。

我在这里做错了什么?

由于我应该返回的变量类型与我要返回的变量类型不匹配,我显然有一个问题。

我……迷失在云端。

【问题讨论】:

  • 除了重新调整悬空指针 (oops) 的事实之外,不要试图猜测 C++ 语法。一个一个地分配元素。顺便说一句,从数学的角度来看,您的 z 案例看起来很有趣。其实还有其他错误吗?看起来你已经滑倒了几个标志。行列式是1吗?你检查一下 - 我太老了。
  • 即使您返回一个指向堆栈对象的指针这一事实也表明您确实迷路了。忘记所有这些,找一本好书并使用 std::vector。
  • 这是 C 骗子 (stackoverflow.com/q/8886375/2602718)。 C++ 的答案可能是“使用向量”。
  • 在我看来,答案是使用线性代数库中的矩阵类:我使用 BLAS,它是 Boost 分布的一部分。
  • 这看起来像一个旋转矩阵。如果是这种情况,你将要做矩阵数学,你应该使用线性代数库中的矩阵类来简化你的生活。

标签: c++ arrays


【解决方案1】:

有一个紧急版本给你。

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
void makeMatrix (const char c, const double a, double *mtx) {
    double matrix[3][3];
    for (int i=0; i<3; i++)
        for (int j=0; j<3; j++) matrix[i][j] = (i == j)? 1.0 : 0.0;
    switch (c) {
        case 'x' :
            matrix[1][1] = cos(a);
            matrix[1][2] = -sin(a);
            matrix[2][1] = sin(a);
            matrix[2][2] = cos(a);
            break;
        case 'y' :
            matrix[0][0] = cos(a);
            matrix[0][1] = -sin(a);
            matrix[2][0] = sin(a);
            matrix[2][2] = cos(a);
            break;
        case 'z' :
            matrix[0][0] = cos(a);
            matrix[0][1] = -sin(a);
            matrix[1][0] = sin(a);
            matrix[1][1] = cos(a);
            break;
    }
    std::copy_n(&matrix[0][0], 9, mtx);
    return;
}
int main()
{
    double mtx[3][3];
    makeMatrix('x', M_PI/3.0, &mtx[0][0]);
    for (int i=0; i<3; i++)
    {
        for (int j=0; j<3; j++) std::cout << mtx[i][j] << ",  ";
        std::cout << std::endl;
    }
}

【讨论】:

  • std::copy_n(&amp;matrix[0][0], 9, mtx); 看起来像 UB,虽然它可能可以工作。
  • 谢谢,但我实际上是为了更“聪明”的东西,因为我想避免输入几个“matrix[i][j]”。我也有兴趣学习一般的“操作方法”,而不仅仅是如何解决这个问题。初始化后必须有某种方法可以在一行中填充矩阵,不是吗?但是,尽管如此,谢谢你。 :)
  • @JimmyScionti 我明白了。我有一个矩阵类,但这对于学习目的来说太大了。我可以给你做一个小的。使用矩阵的初始化列表绝对不是一件简单的工作。你现在可以把它收起来。
  • @JimmyScionti 使用 std::initializer_list > 对矩阵进行大括号初始化。您必须编写一个带有构造函数的矩阵类,该构造函数将此嵌套的 std::initializer_list 作为参数。现在有点复杂。
  • @TedLyngmo '谢谢'。这是“伟大的”。
【解决方案2】:

这是一个简单的模板矩阵类,带有括起来的构造函数。将其保存为 tMatrix.h,并将其与 .cpp 文件一起放在您的工作目录中。

#ifndef __matrix_class___
#define __matrix_class___
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
template <typename T> class tMatrix
{
 public:
     T *ptr;
     int col, row, size;
     inline T* begin() const {return ptr;}
     inline T* end() const {return this->ptr + this->size;}
     inline T operator()(const int i, const int j)const { return ptr[i*col+j]; }
     inline T&operator()(const int i, const int j) { return ptr[i*col+j]; }
     inline tMatrix(): col{0}, row{0}, size{0}, ptr{0} {;}
     tMatrix(const int i, const int j): col(j), row(i), size(i*j)
     {
         ptr = new T [this->size] ;
     }
     tMatrix(const std::initializer_list< std::initializer_list<T> > s):tMatrix<T>(s.size(), s.begin()->size())
     {
        int j = 0;
       for (const auto& i : s) {  std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
     }
     tMatrix(const tMatrix<T>&a) : tMatrix<T>(a.row, a.col)
     {
         std::copy(a.begin(), a.end(), this->ptr);
     }
     tMatrix& operator=(const tMatrix<T>&a)
     {
         std::copy(a.begin(), a.end(), this->ptr);
         return *this;
     }
    ~tMatrix() {delete [] this->ptr;}
 };
 template <typename X> std::ostream& operator<<(std::ostream&p, const tMatrix<X>&a)
{
    p << std::fixed;
    for (int i=0; i<a.row; i++) {
        for (int j=0; j <a.col; j++) p << std::setw(12) << a(i, j);
        p << std::endl;
    }
    return p;
}
using iMatrix = tMatrix<int>;
using rMatrix = tMatrix<double>;
using cMatrix = tMatrix<std::complex<double> >;
#endif

然后修改你的程序为:

#include <cmath>
#include "tMatrix.h"
using namespace std;
rMatrix makeMatrix (const char c, double a) {
   rMatrix mtx(3,3);
   double cs = cos(a), ss = sin(a);
   switch (c) {
       case 'x' :
          mtx = rMatrix( { {1, 0, 0}, {0, cs, -ss}, {0, ss, cs} } );
          break;
       case 'y' :
          mtx = rMatrix( { {cs, 0, ss}, {0, 1, 0}, {-ss, 0, cs} } );
          break;
       case 'z' :
          mtx = rMatrix( { {cs, -ss, 0}, {ss, cs, 0}, {0, 0, 1} } );
          break;
       default:
          break;
     }
   return mtx;
}
int main()
{
  char axis = 'x';
  double angle = M_PI / 180. * 60.;
  rMatrix mtx = {{0,0,0}, {0,0,0}, {0,0,0}}; //initial a 3x3 matrix with all 0s
  std::cout << mtx << std::endl;
  std::cout << makeMatrix(axis, angle) <<std::endl;
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    • 2011-07-18
    • 2020-10-30
    • 2018-08-21
    • 2021-04-04
    • 1970-01-01
    相关资源
    最近更新 更多