【问题标题】:How do I pass multi-dimensional arrays of unknown size into a function using pointers in c++?如何使用 C++ 中的指针将未知大小的多维数组传递给函数?
【发布时间】:2011-05-25 18:48:45
【问题描述】:

正如问题所说,我正在尝试将多维数组传递给一个函数,以将其打印到工程项目的文件中。输入数据的格式不能更改,所以请不要建议我只是输入为不同的数据类型。

这个特殊的函数需要一个二维数组(尽管我在这个数组之后还有其他的三个维度),在运行时之前对数组的大小一无所知。我知道我必须使用指针分别指向数组的每一行,但我不知道将它传递给函数的语法是什么。在下面的代码中,有问题的数组是“块”。 main 函数只是我为使其工作而制作的一个小测试示例:

#include<fstream>
using namespace std;

void of_write_blocks(string filename, string block_type[], int **block,
            int grid[][3], string grade_type[], int grade[][3], int n_blocks, int m[])
{
    ofstream file_out(filename.c_str(),ios::app);
    file_out<<"\nblocks\n(\n";

    for(int i=0;i<n_blocks;++i) {
            file_out<<"   "<<block_type[i]<<" ( ";
                    for(int j=0;j<m[i];++j)
                            file_out<<block[i][j]<<" ";
            file_out<<") ( ";
            file_out<<grid[i][0]<<' '<<grid[i][1]<<' '<<grid[i][2]<<" ) ";
            file_out<<grade_type[i]<<" ( ";
            file_out<<grade[i][0]<<' '<<grade[i][1]<<' '<<grade[i][2]<<" )\n";
    }
    file_out<<");\n";
}


//testing example:
int main()
{       
    int block[6][9];
    for(int i=0; i<6;++i) 
            for(int j=0; i<9;++j)
                    block[i][j] = i*j;

    int grid[6][3];
    for(int i=0; i<6;++i)
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;


    int grade[6][3];
    for(int i=0; i<6;++i) 
            for(int j=0; i<3;++j)
                    block[i][j] = i*j;

    string grade_type[6] = {"simpleGrading"};
    string block_type[6] = {"hex"};
    int m[6] = {8};
    int n_blocks = 6;

    of_write_blocks("name",block_type,block,grid,grade_type,grade,n_blocks,m);
}       

感谢任何帮助!

【问题讨论】:

  • 在过去的 25 年里,我从来没有,一次也没有,不得不使用多维数组。我错过了什么吗?
  • @Neil Butterworth 尝试解决三个维度上的最大和连续子序列问题。我在 C++ 中使用 std::vectors 实现了我的,它需要 4 维数组。
  • @user1344784 很公平 - 听起来像是我和我的各个雇主对解决的兴趣为零的问题。但是如果我要解决这些问题,我想我会使用一种 MDA 是一流对象的语言,比如 FORTRAN,在这个问题领域几乎肯定会比 C++ 性能更高。
  • @Neil Butterworth,我真希望有另一种方法。我将这个程序用于计算流体动力学,这就是他们需要输入的方式。 C++ 对进行与工程相关的计算可能会很麻烦,尤其是考虑到我在学习 C++ 之前就学习了 Matlab!
  • @Mike 流体动力学是 FORTRAN 擅长的经典领域,提供了许多函数库。使用 C++ 似乎是纯粹的受虐狂。

标签: c++ arrays function pointers


【解决方案1】:

你不能。多维数组是语法糖,直接编译到对数组进行操作的代码中,数组是单个内存块。维度不会作为参数或任何类似的东西作为数组的一部分传递给函数,因为事情是在例如完成的。 Java 或 C#。

如果您在函数中需要数组的维度,您只需要接受指向数组第一个元素的指针和维度,然后自己进行乘法和加法以获得正确的索引。

或者,使用std::vector&lt;std::vector&lt;block&gt;&gt; 之类的东西,它将维度作为对象的一部分而不是内置数组传递。

【讨论】:

  • 好的,尺寸输入到函数中,很有帮助。我不确定如何将数组传递给函数,并让函数将其作为指针。你能给我一个这个语法的简单例子吗?
  • 没有std::array&lt;block&gt;这样的东西,你忘了size参数。
  • @Fred:哎呀。固定的。您可以使用std::array 的大小作为大小参数来制作方法模板,但这可能不是一个好主意....
  • 嗨,Billy,您能否给我一个示例,说明如何将数组作为指针传递给函数,该指针仅引用数组第一个元素的地址。我不确定语法是什么。我想这就是你在第二段中的意思吗? (如有错误请指正)
  • @Mike N.void myfunction(block *multiDimensionalArray);
【解决方案2】:

如果您安装了 Boost,请查看 Boost Multi-Array

【讨论】:

  • 阅读。他无法更改数据类型。
  • @user1344784:对不起,我不明白你的评论。你能强调你的评论和我的建议之间的联系吗?谢谢。
  • OP说他不能改变数据类型,那你为什么推荐Boost Multi-Array???
  • @user1344784:嗯,这是一个通用的解决方案,如果他只对一种类型进行操作,那就这样吧。 Boost Multi-array 并不要求您更改类型。
【解决方案3】:

为清楚起见,我从您的示例中删除了所有不相关的代码。

#include <iostream>
#include <fstream>

using namespace std;

void of_write_blocks(int **block, int bh, int bw){

  for(int i = 0; i < bh; ++i)
    for(int j = 0; j < bw; ++j)
      cout << block[i][j] << " ";
  cout << endl;
}

int main(){       

  int bh, bw;
  cin >> bh >> bw;

  int** block;
  block = new int*[bh];
  for(int k = 0; k < bh; k++)
    block[k] = new int[bw];

  // initialize the array
  for(int i = 0; i < bh; i++)
    for(int j = 0; j < bw; j++)
      block[i][j] = (i*bw) + j;

  of_write_blocks( block, bh, bw);
}       

我们主要是创建一个二维数组并对其进行初始化。然后我们将它传递给 of_write_block,它会打印数组。那是你想做的吗?

【讨论】:

  • 这里的问题是数组的大小在运行时是未知的,因此将它们声明为常量是行不通的。该函数需要以数组的形式接受输入,并将维度作为局部整数直接输入到函数调用中,而不是作为全局常量。
  • @Mike N. 数组大小可以是动态的。我更改了代码以反映这一点。至于数组大小,您必须将大小传递给示例中的函数。没有其他方法可以知道大小。
【解决方案4】:

为什么不能使用数组的引用。见下例:

char c[10];
int i[10][20];
double d[10][20][30];

像这样写一个包装器函数:

template<typename T, int SIZE>
void Array (T (&a)[SIZE])
{}
template<typename T, int SIZE1, int SIZE2>
void Array (T (&a)[SIZE1][SIZE2])
{}
template<typename T, int SIZE1, int SIZE2, int SIZE3>
void Array (T (&a)[SIZE1][SIZE2][SIZE3])
{}

这只是一个示例,用于演示无需任何复制即可优雅地接收数组并避免混淆指针的语法。此外,如果您知道您将只用于int,那么只需删除类型名并明确提及int。即

template<int SIZE>
void Array (int (&a)[SIZE]); // explicitly mention int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-27
    • 2016-09-02
    • 1970-01-01
    • 2018-07-10
    • 2014-05-09
    • 1970-01-01
    • 2016-04-27
    • 2019-03-28
    相关资源
    最近更新 更多