如何从用户定义的函数返回 3D 数组?
Posted
技术标签:
【中文标题】如何从用户定义的函数返回 3D 数组?【英文标题】:How to return a 3D array from user defined function? 【发布时间】:2020-11-15 02:49:27 【问题描述】:我想将用户定义函数中的 3 维数组返回到我的 main
函数中。
让我们考虑一个简单的例子,用于 a
、b
和 c
数组的任何特定值;
int*** my_function(int a[], int b[], int c[])
for (int i = 0; i < 2; i++)
for (int j; j < 2; j++)
for (int k; k < 2; k++)
array[i][j][k] = a[i] * b[j] * c[k];
return array
【问题讨论】:
我建议使用向量,使用它你不必考虑指针。std::array
?
假设三个维度都固定为2
,返回一个std::array<std::array<std::array<element_type, 2>, 2>, 2>
【参考方案1】:
我已经得到了你想要的东西
#include <iostream>
using namespace std;
int** form_2d_array(int l, int b)
int **A = new int *[b];
for (int i = 0; i < b; i++)
A[i] = new int[l];
return A;
int*** form_3d_array(int l, int b, int h)
int ***A = new int **[h];
for (int i = 0; i < h; i++)
A[i] = form_2d_array(l,b);
return A;
int main()
int ***array;
int l,b,h;
l=3;b=5;h=3;
array=form_3d_array(l,b,h);
for (int i = 0; i < l; i++)
for (int j=0; j < b; j++)
for (int k=0; k < h; k++)
array[i][j][k] = i+j+k;
for (int k=0; k < h; k++)
cout<<"Printing "<<k+1<<"th matrix\n";
for (int i = 0; i < l; i++)
for (int j=0; j < b; j++)
cout<<array[i][j][k]<<" ";
cout<<endl;
cout<<endl;
return 0;
2d 数组函数返回一个 2d 数组,3d 数组函数返回一个 3d 数组。
【讨论】:
【参考方案2】:使用指针的更好替代方法是使用std::vector
,因为它会处理内存分配和释放的细节。
如何初始化 3D 矢量?
3D 向量只是一个包含两个其他向量的向量。所以,如果你想用值 A 初始化一个大小为 X * Y * Z 的 3D 向量。那么它可以这样做:
vector<vector<vector<int> > > vec (X,vector<vector<int> >(Y,vector <int>(Z,A)))
如何从函数中返回它?
您可以从下面的示例中看到如何返回它。
vector<vector<vector<int> > > sample_function()
//sample code
return vec;
【讨论】:
嵌套向量的缺点是它在后台进行指针解引用。对于 3D 向量,这意味着它必须取消引用 3 个指针。这比拥有一维向量并使用一些算术将 3 个索引转换为一维向量的一个偏移量效率低。所以在这种情况下,它可能看起来像:std::vector vec(2 * 2 * 2); ...; vec[i + 2 * (j + 2 * k)] = a[i] * b[j] * c[k];
您的示例函数将具有未定义的行为,除非您在循环之前设置(外部向量以及递归地包含向量的)维度。 vector
s operator[]
不能确保提供的索引有效。【参考方案3】:
请注意:int ***
不适合返回 3D 数组。最多可以用来返回一个指向指针数组的指针。
由于原始数组不是 C++ 语言中的第一类元素,因此您不能以简单自然的方式从函数返回数组。
可以做什么?
C++ 简单方法:
不要使用原始数组,但std::array
是在编译时固定的大小,或者std::vector
如果不是。然后,您可以构建(并返回向量的向量或std::array
的std::array
。请注意向量向量就像一个指针数组:数据不需要是连续的,因此它不等同于 3D 数组。这里,假设固定大小:
std::array<std::array<std::array<int, 2>, 2>, 2> my_function(int a[], int b[], int c[])
std::array<std::array<std::array<int, 2>, 2>, 2> array;
...
return array;
自定义容器(仍然是现代 C++)
如果您需要在 C++ 中模拟一个 3D 连续容器并让它表现得像一个普通对象(可以从函数返回),您将必须构建一个自定义容器及其访问器方法。它不是非常复杂,但远非微不足道。如果你想这样做,我的建议是使用 (1D) 向量作为底层存储,以免被原始分配存储的复制、移动、破坏问题所困扰。
C-ish 方式(使用原始数组)。
多维数组必须具有所有维度,但最后一个维度是在编译时定义的。说了这么多,你还是会找到 3 种常见的 C 存储方式:静态存储(可以安全返回,但不是线程安全的)、分配存储(线程安全,但调用者将负责释放它)、调用者提供( caller 负责创建数组并将其传递给被调用函数。我将在这里向您展示第三种方式
typedef int (*int3D)[2][2];
int3D my_function(int a[], int b[], int c[], int3D array)
for(int i=0; i<2; i++)
...
return array;
用法:
int arr[2][2][2];
int3D arr3D = my_function(a, b, c, arr);
// after the call, arr3D == arr is true
【讨论】:
【参考方案4】:正如其他人提到的,您可以使用std::array
或std::vector
,但一种简单的方法是将数组作为参数传递给您的函数(而不是返回)。像这样的……
void your_function(int array[2][2][2], /* other parameters */)
// body
并像这样使用它:
int main()
int arr[2][2][2];
your_function(arr, /* other arguments */);
// now do what you want with arr
【讨论】:
【参考方案5】:您可以使用std::array
。
如果大小是已知的编译时间,我建议使用std::array
,通过它您可以获得连续的内存布局。
#include <iostream>
#include <array>
#include <algorithm> // std::generate
// alias for the required array
using Array3D = std::array<std::array<std::array<int, 2>, 2>, 2 >;
Array3D func()
Array3D arr3d;
std::array<int, 2> a 10, 20 , b 10, 20 , c 10, 20 ; // some a, b, c
// iterate through the arrays to initialize them!
auto input = 1u;
for (std::array<std::array<int, 2>, 2> & array2D : arr3d) // or auto& array2D: arr3d
for (std::array<int, 2> & arr : array2D) // or auto& arr: array2D
std::generate(arr.begin(), arr.end(), [&input] return input++; );
// for array multimplications!
for (std::array<std::array<int, 2>, 2> & array2D : arr3d) // or auto& array2D
for (std::array<int, 2> & arr : array2D) // or auto& arr
auto arrIndex = 0u;
for (int& ele : arr)
ele = a[arrIndex] * b[arrIndex] * c[arrIndex];
++arrIndex;
std::cout << ele << " "; // to print the element!
return arr3d; // return the array like this!
或者使用模板函数(将大小作为非模板参数),您甚至可以通过引用传递array3d
并按照上面显示的方式进行计算!
#include <iostream>
template<std::size_t M, std::size_t N, std::size_t O>
void func(int (&arr3d)[M][N][O])
// some a, b, c
for (std::size_t i = 0; i < M; ++i)
for (std::size_t j = 0; j < N; ++j)
for (std::size_t k = 0; k < O; ++k)
arr3d[i][j][k] = a[k] * b[k] * c[k];
std::cout << arr3d[i][j][k] << " "; // to print the element
std::cout << "\n";
std::cout << "\n";
// do not need to return!
【讨论】:
以上是关于如何从用户定义的函数返回 3D 数组?的主要内容,如果未能解决你的问题,请参考以下文章