【问题标题】:Set a pointer to a static 2D array设置指向静态二维数组的指针
【发布时间】:2014-07-12 23:33:00
【问题描述】:

如何在类中设置指向外部静态数据结构的指针?

struct Str {
    double **matr;   // which type should matr be?
    int nx, ny;

    template<size_t rows, size_t cols>
    void Init(double(&m)[rows][cols], int sx, int sy) {
        matr = m;     // <-- error
        nx = sx; ny = sy;
    }
};
...
static double M[3][5] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                          { 0.1, 1.1, 2.1, 3.1, 4.1 },
                          { 0.2, 1.2, 2.2, 3.2, 4.2 } };
Str s;
s.Init(M, 3, 5);

使用此代码,我收到以下编译时错误消息 (Visual C++ 2008/2012):

1> 错误 C2440:“=”:无法从“double [3][5]”转换为“double **”
1> 指向的类型不相关;转换需要 reinterpret_cast、C 样式转换或函数样式转换
1> 参见正在编译的函数模板实例化 'void S::Init4(double (&)[3][5],int,int)' 的参考

【问题讨论】:

  • 你对M的过度使用可能会让人感到困惑——你有Mdoubles的静态数组和Mvoid Str::Init()函数的模板参数。您打算double (*m)[M] 参考哪一个?我想你希望你的mattr 只是double *mattr,或者更丑的double (*mattr)[5]...
  • @twalberg - 谢谢,我修好了。
  • double(*m)[S] 是什么意思?是函数指针数组吗?
  • @Cool_Coder - 这是一个二维数组。现在应该更清楚了。
  • 好的,有什么问题吗?没有编译吗?

标签: c++ arrays pointers


【解决方案1】:

问题在于double 的二维数组不是指针数组,它只是指向二维数组第一个元素的单个指针,由内存中的几行连续的双精度数表示。

由于您的struct 具有字段nx/ny,因此您可以将数组转换为简单指针,然后使用nx/ny 访问它,即:

struct Str {
    double *matr;
    int nx, ny;

    void Init(double* m, int sx, int sy) {
        matr = m;
        nx = sx; ny = sy;
    }
};

static double M[3][5] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                          { 0.1, 1.1, 2.1, 3.1, 4.1 },
                          { 0.2, 1.2, 2.2, 3.2, 4.2 } };

int main() {
    Str s;
    s.Init(M[0], 3, 5);
    return 0;
}

然后您必须使用 nx/ny 来访问数组,例如这是一个可以添加到打印数组的struct Str 的函数:

#include <iostream>

void print() {
    for (int i = 0; i < nx; i++) {
        for (int j = 0; j < ny; j++) {
            std::cout << matr[i*ny+j] << " ";
        }
        std::cout << std::endl;
    }
}

另一个(可以说是更好的)解决方案是将模板参数添加到 struct Str 以替换 nx/ny,然后 matr 成员可以具有包含维度的类型。

【讨论】:

  • 如果我在结构中使用模板参数,我必须在定义对象时指定尺寸。我可以在成员函数上使用模板来选择稍后调整对象的大小吗?参考:user2079303的回答。
【解决方案2】:

所以,你想要一个指向二维数组的指针。 Str 必须是一个模板,因为它的成员 matr 的类型取决于该数组的维度。

template<int rows, int cols>
struct Str {
    double (*matr)[rows][cols];

    void Init(double(&m)[rows][cols]) {
        matr = &m;
    }
};

Str<3, 5> s;
s.Init(M);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    相关资源
    最近更新 更多