【问题标题】:Passing pointer of multi-dimensional pointer array to a function将多维指针数组的指针传递给函数
【发布时间】:2018-03-08 23:35:02
【问题描述】:

好吧,假设我有一个函数myFunction。然后在main 我有一个多维指针数组。我想将指向这个指针数组的指针传递给myFunction。我该怎么做?我知道如果你想将int 传递给我的函数,可以将函数写为

myfunct( int x) { ...}

如果我必须将一个指针传递给一个指针数组,那么这种类型的 x 会是什么?在此先感谢:D

【问题讨论】:

  • 为什么不直接传递对vector 指针的引用?
  • 视情况而定。您的实际确切类型是什么?

标签: c++ arrays pointers


【解决方案1】:

通常你想修改数组的元素而不是实际的指针。实际指针由malloc 给出,如果您更改它,通过直接写入该值,它不会影响内存分配(除非您可能会丢失初始指针......)。

这可能是您在二维数组中寻找的内容。

void myfunct(int** ptr,int items, int array_items)
{
    //some code
}
int main(int argc, char *argv[])
{
    const auto items = 5;
    const auto array_items = 7;
    int** multi_dimensional_array = reinterpret_cast<int**>(std::malloc(items * sizeof(int*)));
    for (auto i = 0 ;i < items;++i)
    {
        multi_dimensional_array[i] = static_cast<int*>(std::malloc(sizeof(int) * array_items));
    }
    myfunct(multi_dimensional_array,items,array_items);
    //deallocate
}

【讨论】:

  • malloc 最好保留给那些无法使容器或new 工作的奇怪边缘情况。
  • deimsional - 这是一个新的!
  • @LightnessRacesinOrbit 大声笑,我的手机上没有一个好的拼写检查器,也是我在献血时写的。你可以告诉它的 C++,因为我使用了 std::malloc + static_cast
  • @Mikhail:我喜欢这个新词——可能会开始使用它!
  • 感谢献血。
【解决方案2】:

将您的多维数组包装在一个类中。这样你就可以在一个块中携带数据和维度,并且传递它就像在任何其他类中移动一样简单。

记得观察the Rules of Three, Five, and Zero,以最适合您在类中存储数组的方式为准。 std::vector 是个人最爱,因为它允许您使用零规则。

例如:

#include <iostream>
#include <vector>

struct unspecified
{
};

template<class TYPE>
class TwoDee{
    int rows;
    int cols;
    std::vector<TYPE> data;
public:
    TwoDee(int row, int col):rows(row), cols(col), data(rows*cols)
    {
        // does nothing. All of the heavy lifting was in the initializer
    }
    // std::vector eliminates the need for destructor, assignment operators, and copy
    //and move constructors. All hail the Rule of Zero!
    //add a convenience method for easy access to the vector
    TYPE & operator()(size_t row, size_t col)
    {
        return data[row*cols+col];
    }
    TYPE operator()(size_t row, size_t col) const
    {
        return data[row*cols+col];
    }
};

void function(TwoDee<unspecified *> & matrix)
{
    // does stuff to matrix
}

int main()
{
    TwoDee<unspecified *> test(10,10);
    function(test);
}

【讨论】:

    【解决方案3】:

    为了直接回答您的问题,对于int 的向量,传递的类型通常是int *,对于int 的二维数组,传递的类型是int **

    void myfunct( int **x) 
    { 
        x[2][1] = 25;
        return;
    }
    

    如果出于某种原因您希望它是 int 指针数组而不是 int 您需要一个额外的 *。

    void myfunct( int ***x) 
    { 
        *(x[2][1]) = 25;
        return;
    }
    

    【讨论】:

    • 是的,但这是一个指针数组,我如何为指针数组做到这一点?
    • 我更新为显示 int 指针而不是 int 的语法。通常,内存将被布置在一个块中,以便可以单独使用索引运算符,这与您在其他语言中看到的锯齿状数组不同。指针数组通常只用于类对象,而不是原始类型。
    【解决方案4】:

    让我首先尝试解释您要处理的确切类型。我想在你的main 函数中有一个“多维数组”,它存储每个元素的指针。例如,假设您有一个指向整数类型的 3 维数组。

    假设你知道数组的大小:

    C 样式数组将如下所示:

    int *a[4][3][2];
    

    这意味着a 是一个 4x3x2 数组,数组中的每个元素都是一个指向整数的指针。所以总的来说,你现在总共有 24 个指向整数的指针,通过测试 sizeof(a) / sizeof(int*) 的结果可以看出(结果应该是 24)。好的,到目前为止一切顺利。但是现在我猜你想要的是一个指向上面提到的数组a 的指针,比如说b,所以定义了b

    int *(*b)[4][3][2] = &a;
    

    请注意,虽然现在b 看起来很吓人,但最终它只是一个只存储地址的指针,sizeof(b) / sizeof(int*) 给出的结果是 1。 (括号内的* 表示b 是指针类型,所以b 是指向整数指针的“多维数组”的指针。)

    现在将b 传递给myFunction,只需在声明中给出与参数类型相同类型的b

    void myFunction(int *(*x)[4][3][2]) {
        // do something
    }
    

    就是这样!您可以直接使用myFunction(b) 调用该函数。另外,你可以在myFunction内部测试,x还是一个指针大小,*x是24个指针大小。

    *请注意,由于我们将指向数组类型的指针传递给函数,因此此处不适用数组到指针的衰减。

    假设你在编译时不知道数组的大小:

    假设你有int N1 = 4, N2 = 3, N3 = 2;,并且你想初始化一个指向整数的 N1xN2xN3 数组,你不能直接在堆栈上这样做。

    您可以按照@Mikhail 的回答中的建议初始化使用newmalloc,但是这种方法对多维数组采用嵌套循环,并且在释放内存时需要再次执行嵌套循环。所以正如@user4581301 所建议的那样,std::vector 为动态大小的数组提供了一个很好的包装器,它不需要我们自己释放内存。对!

    想要的数组a可以这样写(看起来还是有点丑,但是没有显式循环和释放内存的麻烦)

    std::vector<std::vector<std::vector<int*>>> a (N1,
        std::vector<std::vector<int*>> (N2,
            std::vector<int*> (N3)
        )
    );
    

    现在,b(指向a的指针)可以写成

    auto *b = &a;
    

    您现在可以将b 传递给

    void myFunction(std::vector<std::vector<std::vector<int*>>>* x) {
        // do something
    }
    

    注意x前面的*表示x是一个指针。

    【讨论】:

      猜你喜欢
      • 2017-04-18
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 2012-03-13
      • 2013-02-15
      • 1970-01-01
      相关资源
      最近更新 更多