如何将简单指针转换为固定大小的多维数组?

我有一个函数,它采用指向浮点数组的指针。 基于其他条件,我知道指针实际上指向2×2 OR 3×3矩阵。 (实际上内存最初是这样分配的,例如float M [2] [2])重要的是我想在函数体中做出这个决定,而不是作为函数参数。

void calcMatrix( int face, float * matrixReturnAsArray ) { // Here, I would much rather work in natural matrix notation if( is2x2 ) { // ### cast matrixReturnAsArray to somethingAsMatrix[2][2] somethingAsMatrix[0][1] = 2.002; // etc.. } else if(is3x3) { //etc... } } 

我知道我可以使用模板和其他技术来更好地解决这个问题。 我的问题是关于如何在###评论中进行这样的演员表。 使用C ++。

 float (*somethingAsMatrix)[2] = (float (*)[2]) matrixReturnAsArray; 

float *可以指向float *的第一个元素,并且应该对该数组类型进行reinterpret_castable。 并且该转换的结果可能指向float [][]的第一个元素,因此应该将reinterpret_castable指向该类型,依此类推。 你应该能够组成这样的演员而且直接做

 float (&arr)[2][2] = *reinterpret_cast(matrixReturnAsArray); 

float **类型的参数不相同,不应该以这种方式使用。

为了避免未定义的行为,指针必须来自实际的多维数组,如果直接使用float*则不能访问多维矩阵的第一行。

 void foo(float *f) { f[3] = 10.; float (&arr)[2][2] = *reinterpret_cast(f); arr[1][1] = 10.; } void main() { float a[2][2]; foo(&a[0][0]); // f[3] = 10.; is undefined behavior, arr[1][1] = 10. is well defined float b[4]; foo(&b[0]); // f[3] = 10.; is well-defined behavior, arr[1][1] = 10. is undefined } 

鉴于float arr[2][2]; 没有任何保证&arr[0][1] + 1&arr[1][0] ,据我所知。 因此,尽管通过执行f[i*width + j]可以将单维数组用作多维数组,但您无法将多维数组视为单维数组。

最好使用C ++的编译时类型安全,而不是仅仅依赖于不小心传递错误的东西或执行错误的reinterpret_cast。 要使用原始数组获得类型安全性,您应该使用对所需原始数组类型的引用:

 void foo(float (&f)[2][2]) {} void foo(float (&f)[3][3]) {} 

如果你想按值传递数组,你不能使用原始数组,而应该使用类似std :: array的东西:

 void foo(std::array,2> f) {} void foo(std::array,3> f) {} 

通过明智地使用typedef,这种类型的转换总是更干净,更容易处理:

 typedef float Matrix_t[2][2]; Matrix_t* someThingAsMatrix = (Matrix_t*) matrixReturnAsArray; 

但是,如果这是C ++而不是C,则应创建矩阵类。 (或者更好的是,寻找一个开源的。)