真的有可能吗?
我知道如何使用双指针传递二维数组。根据我的理解,它也应该适用于3-D阵列。但是我很想被证明是错误的。这个问题肯定会揭示如何解释数组。
这里的事实是3-D数组是一个连续的块,而不是一些较小块的指针数组。
该程序给我错误:
#include <iostream>
using namespace std;
void display(int ***arr, int l, int m, int n)
{
for(int i=0; i<l; i++)
for(int j=0; j<m; j++)
for(int k=0; k<n; k++)
cout << *(*(*(arr+i)+j)+k) << endl;
}
int main()
{
int arr[][2][2] = {{{1,2},{3,4}},{{10,20},{30,40}}};
display((int***)arr,2,2,2);
}
输出
test.cpp:17:19: error: cannot convert 'int (*)[2][2]' to 'int***' for argument '1' to 'void display(int***, int, int, int)'
display(arr,2,2,2);
^
二维数组传递给双指针 我相信我也可以做类似于3D阵列的事情,但这太糟了,难以阅读。
#include <iostream>
using namespace std;
void display(int **arr, int m, int n)
{
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
cout << *(*(arr+i)+j) << " " << arr[i][j] << endl;
}
int main()
{
int arr[][3] = {{1,2,3},{4,5,6}};
int *temp[2];
for(int i=0; i<2; i++)
temp[i] = *(arr+i);
display(temp,2,3);
}
OUTPUT
1 1
2 2
3 3
4 4
5 5
6 6
答案 0 :(得分:1)
您对2D数组所做的操作是正确的,因为您已经构建了一个辅助指针数组,并且将该指针数组作为int **
进行了传递。即使对于2D阵列,这
void display(int **arr, int m, int n);
...
int arr[][3] = {{1,2,3},{4,5,6}};
display(arr,2,3); // WRONG! use a 2D array as an array of pointers
会错的。
无论如何,C ++标准对多维数组并不友好:无法编写传递未知维的多维数组的严格一致的程序。许多编译器都接受它作为扩展,但是它在其他编译器上可能无法移植。
惯用的方法是仅将一维数组用作基础数据结构,并通过内部进行索引计算来提供将其作为多维容器处理的方法。
顺便说一句,我尝试构建一个具有任意运行时维度的多维连续容器,同时尊重标准容器的所有约束,并在意识到该标准不允许之后放弃了:不可能构建一个对不保存自己数据的对象进行 nice 迭代。这是我最好的attempt。答案和评论解释了为什么它没有希望。
答案 1 :(得分:0)
尽管您可以像这样传递一维数组
$ clang++-7 -g -O3 -std=c++2a locking.cpp -o locking && ./locking
Starting test
With lock took 2099204ns
No lock took 2126724ns
Atomic lock took 12922543ns
实际上,编译器会将void pass1Darray(int a[])
{
statements;
}
int main()
{
int a[10];
pass1Darray(a);
}
视为int a[]
,这就是人们怀疑是否有可能通过pointer_to_pointer传递二维数组的原因。
但这没有意义!
如果要传递2D数组int* a
,则可以将bob视为一个数组,并且其元素是一个数组,并像这样传递它
bob[5][10]
这是关于传递二维数组。
顺便说一句,英语不是我的母语,而且我也是c ++的初学者。
如果出问题了,请告诉我,谢谢。
答案 2 :(得分:0)
在本地int arr[][2][2]
声明数组时,编译器将实例化一维向量,并“记住”偏移量以获取正确的索引。
本地数组也存储在堆栈中,如果您需要大型矩阵,则这不是很好。 int arr[][2][2]
的另一个特性是为什么当您尝试将其作为参数传递给函数时,int arr [] [2] [2] 是类型。您必须指定所有尺寸。
指针的工作方式不同。如果实例化2D数组,则需要为行分配一个指针数组,并分配每个行数组以分别保存数据。在C ++中,我认为最好使用标准库,该库具有动态指针的标准实现,该指针负责所有分配。 std::vector
结论:
答案 3 :(得分:0)
我相信我也可以做类似于3D阵列的事情,但这太糟糕了,难以阅读。
是的,正如n.m.在其评论中解释的那样
在2D代码中,您创建了一个全新的指针数组,将其填充,然后将其传递给函数,而不是原始的2D数组。在您的3D代码中,您没有尝试任何类似的操作。
由于该问题被标记为C ++,因此我们可以使用与C编码人员不同的工具箱。
在C ++中,不仅可以通过值,还可以通过 reference 将参数传递给函数,并且我们可以编写 template ,编译器可以使用该模板来为使用的类型生成正确的函数。
#include <iostream>
#include <iomanip>
template <class T, size_t L, size_t M, size_t N>
void display( T const (&arr)[L][M][N], int width )
// ^^^^^^
{
for (size_t i = 0; i < L; ++i) {
for (size_t j = 0; j < M; ++j) {
for (size_t k = 0; k < N; ++k) {
std::cout << std::setw(width) << arr[i][j][k];
}
std::cout << '\n';
}
std::cout << '\n';
}
}
int main()
{
int arr[3][2][4] = {
{ {1,2,3,4},
{5,6,7,8}
},
{ {10,20,30,40},
{50,60,70,80}
},
{ {100,200,300,400},
{500,600,700,800}
}
};
display(arr, 5);
}
实时HERE。
当然,下一步将是编写一个封装多维数组概念的类。