C++ 以优雅的方式创造&;在c+中传递多维数组+;?
第一个问题: 对于已知维度,我们不需要new/malloc进行创建C++ 以优雅的方式创造&;在c+中传递多维数组+;?,c++,pointers,multidimensional-array,C++,Pointers,Multidimensional Array,第一个问题: 对于已知维度,我们不需要new/malloc进行创建 const int row = 3; const int col = 2; int tst_matrix[row][col] ={{1,2},{3,4},{5,6}} 然而,将这个二维数组传递给另一个函数并不容易,对吗?因为 int matrix_process(int in_matrix[][]) 如果不合法,则必须指定除第一个尺寸外的所有尺寸。如果我需要更改in_矩阵的内容,如何轻松地将t
const int row = 3;
const int col = 2;
int tst_matrix[row][col] ={{1,2},{3,4},{5,6}}
然而,将这个二维数组传递给另一个函数并不容易,对吗?因为
int matrix_process(int in_matrix[][])
如果不合法,则必须指定除第一个尺寸外的所有尺寸。如果我需要更改in_矩阵的内容,如何轻松地将tst_矩阵传递给函数矩阵_过程
第二个问题:
用C++创建二维数组的标准方法是什么?我不想使用std::vector等。。在这里
这就是我想到的,这是最好的方法吗
int **tst_arr = new int*[5];
int i=0, j=0;
for (i=0;i<5;i++)
{
tst_arr[i] = new int[5];
for (j=0;j<5;j++)
{
tst_arr[i][j] = i*5+j;
}
}
int**tst_arr=newint*[5];
int i=0,j=0;
对于(i=0;i多维数组,如果所有边界在运行时都是可变的,我所知道的最常见的方法是使用动态分配的一维数组,并“手动”进行索引计算在C++中,通常使用一个类,如<代码> STD::vector < /Cl>专业化,管理这个数组的分配和分配。
这与固定边界的多维数组的布局基本相同,没有任何固定的开销,任何方法都需要在运行时将数组中的所有条带传递到运行时。
< P>我认为最好的办法是避开原始的C++数组,而不是包装类。multi_数组类型。这消除了原始数组中出现的各种奇怪现象(难以将它们的参数传递给函数,跟踪数组大小的问题,等等)
另外,我强烈建议您重新考虑一下您对std::vector的立场。它比原始数组安全得多,因此在大多数情况下,在向量上使用动态数组并不是一个很好的理由。如果您有C背景,那么花时间进行切换是值得的。1)
template
二等舱{
公众:
静态常量大小\u t行=行;
静态常量大小=列;
/* ... */
T在[行][Col];
};
模板
int矩阵_过程(T&in矩阵){
在[0][0]处的_矩阵中返回T::Row*T::Col+;
}
2) 使用std::vector。您正在添加一些函数调用(可能在优化的构建中内联),并且可能正在导出一些额外的符号。我想有很好的理由来避免这种情况,但适当的理由是非常罕见的。简单的答案是,C++中的优雅方法(你标记C和C++,但是你的代码是C++ <代码>新的< /代码> /<代码>删除< /代码>)是通过创建一个二维类并通过引用(或引用)来传递。在那之后,下一个选项应该始终是std::vector
(同样,我将根据向量实现矩阵类)。除非您有非常令人信服的理由,否则我将避免处理原始数组
如果确实需要,但只有在确实需要的情况下,才可以完美地使用多维数组,这比使用普通数组要麻烦一些。如果所有维度在编译时都是已知的,就像在第一个块中一样,这是一些选项
const unsigned int dimX = ...;
const unsigned int dimY = ...;
int array[dimY][dimX];
void foo( int *array[dimX], unsigned int dimy ); // [1]
void foo( int (&array)[dimY][dimX] ); // [2]
在[1]中,通过使用按值传递
语法,数组将衰减为指向第一个元素的指针,这意味着指向int[dimX]
的指针,这就是您需要传递的内容。请注意,您应该在另一个参数中传递另一个维度,因为函数中的代码不知道这一点。在[2]中,通过向数组传递一个引用,所有维度都是固定的和已知的。编译器将确保仅使用适当大小的数组(两个维度一致)调用,因此无需传递额外的参数。第二个选项可以模板化,以适应不同的大小(所有大小都在编译时已知):
模板
void foo(整数和数组)[DimY][DimX]);
编译器将扣除大小(如果将实际数组传递给模板),您将能够在模板内使用它作为DimX
和DimY
。这允许使用具有不同数组大小的函数,只要它们在编译时都是已知的
如果在编译时不知道维度,那么事情就会变得非常混乱,唯一明智的方法就是将矩阵封装在一个类中。基本上有两种方法。第一种方法是分配一个连续的内存块(就像编译器在前面的例子中所做的那样),然后提供按二维索引该块的函数。查看第一段中的链接,了解一种简单的方法,即使我会在内部使用std::vector
而不是原始指针。请注意,对于原始指针,您需要在销毁时手动管理指针的删除,否则您的程序将泄漏内存
另一种方法,也就是你在问题的第二部分中开始的方法,是我无论如何都要避免的方法,它包括将一个指针保存到一个整数指针块中。这使内存管理变得复杂(您从必须删除一个指针变成必须删除DimY+1
指针——每个array[i]
,再加上array
),并且您还需要在分配期间手动保证所有行包含相同数量的列。可能出现错误而没有收益的事情的数量大幅增加,但实际的损失(保存中间指针所需的内存更多,运行时性能更差,因为您必须重复引用,数据的局部性可能更差
包装:编写一个类,以连续内存块的形式封装二维对象(数组,如果编译时大小已知--为不同的编译时大小编写模板--,std::vector
如果直到运行时才知道大小,则仅当
#include <iostream>
using namespace std;
//Input Matrix--a: Array[M][N]
int change_row_col( int **a)
{
int i,j;
int* row = new int[5];
int* col = new int[5];
//initialization
for(i=0;i<5;i++)
{
row[i]=0;
}
for(j=0;j<5;i++)
{
col[j]=0;
}
//check which element is 0
for (i=0; i<5; i++)
for(j=0;j<5;j++)
{
if (*(*(a+i)+j)==0) //why I can not use a[i][j] here?
{
row[i]=1;
col[j]=1;
}
}
for(i=0;i<5;i++)
for (j=0;j<5;j++)
{
if (row[i] || col[j])
{
*(*(a+i)+j)=0;
}
}
return 1;
}
int main ()
{
int **tst_arr = new int*[5];
int i=0, j=0;
for (i=0;i<5;i++)
{
tst_arr[i] = new int[5];
for (j=0;j<5;j++)
{
tst_arr[i][j] = i*5+j;
}
}
for (i=0; i<5;i++)
{
for(j=0; j<5;j++)
{
cout<<" "<<tst_arr[i][j];
}
cout<<endl;
}
change_row_col(tst_arr);
for (i=0; i<5;i++)
{
for(j=0; j<5;j++)
{
cout<<" "<<tst_arr[i][j];
}
cout<<endl;
}
for (i=0;i<5;i++)
{
delete []tst_arr[i];
}
delete []tst_arr;
}
template < typename T, size_t Row_, size_t Col_>
class t_two_dim {
public:
static const size_t Row = Row_;
static const size_t Col = Col_;
/* ... */
T at[Row][Col];
};
template <typename T>
int matrix_process(T& in_matrix) {
return T::Row * T::Col + in_matrix.at[0][0];
}
const unsigned int dimX = ...;
const unsigned int dimY = ...;
int array[dimY][dimX];
void foo( int *array[dimX], unsigned int dimy ); // [1]
void foo( int (&array)[dimY][dimX] ); // [2]
template <unsigned int DimX, unsigned int DimY>
void foo( int (&array)[DimY][DimX] );
template<size_t M,size_t N>
void Fun(int (&arr)[M][N])
{
for ( int i = 0 ; i < M ; i++ )
{
for ( int j = 0 ; j < N ; j++ )
{
/*................*/
}
}
}
void editArray(int M,int N,int matrix[M][N]){
//do something here
}
int mat[4][5];
editArray(4,5,mat); //call in this way