C++ 如何将简单指针转换为固定大小的多维数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11869056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to cast simple pointer to a multidimensional-array of fixed size?
提问by NoahR
I have a function that takes a pointer to a floating point array. Based on other conditions, I know that pointer is actually pointing to a 2x2 OR 3x3 matrix. (in fact the memory was initially allocated as such, e.g. float M[2][2] ) The important thing is I want to make this determination in the function body, not as the function argument.
我有一个函数,它接受一个指向浮点数组的指针。基于其他条件,我知道指针实际上指向一个 2x2 OR 3x3 矩阵。(实际上内存最初是这样分配的,例如 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...
}
}
I am aware that I could use templates and other techniques to better address this problem. My question is really about how to make such a cast at the ### comment. Working in C++.
我知道我可以使用模板和其他技术来更好地解决这个问题。我的问题实际上是关于如何在 ### 评论中进行这样的演员表。在 C++ 中工作。
回答by ecatmur
float (*somethingAsMatrix)[2] = (float (*)[2]) matrixReturnAsArray;
回答by bames53
float *
could point to the first element of an array of floats, and ought to be reinterpret_castable to that array type. And the result of that cast could point to the first element of a float [][]
and so should be reinterpret_castable to that type, and so on. You ought to be able to compose such casts and just directly do
float *
可以指向浮点数组的第一个元素,并且应该 reinterpret_castable 到该数组类型。并且该转换的结果可能指向 a 的第一个元素,float [][]
因此应该 reinterpret_castable 到该类型,依此类推。你应该能够组成这样的演员表,直接做
float (&arr)[2][2] = *reinterpret_cast<float (*)[2][2]>(matrixReturnAsArray);
An argument of the type float **
is not the same and should not be used this way.
类型的参数float **
不同,不应以这种方式使用。
To avoid undefined behavior the pointer must originate from an actual multi-dimensional array, and if the float*
is used directly you cannot access more than the first row of the multi-dimensional matrix.
为了避免未定义的行为,指针必须来自实际的多维数组,如果float*
直接使用,则不能访问多维矩阵的第一行。
void foo(float *f) {
f[3] = 10.;
float (&arr)[2][2] = *reinterpret_cast<float (*)[2][2]>(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
}
Given float arr[2][2];
nothing guarantees that &arr[0][1] + 1
is the same as &arr[1][0]
, as far as I have been able to determine. So although you can use a single dimensional array as a multi-dimensional array by doing f[i*width + j]
you cannot treat a multi-dimensional array like a single dimensional array.
鉴于float arr[2][2];
没有任何保证&arr[0][1] + 1
与 相同&arr[1][0]
,据我所知。因此,尽管您可以通过这样做f[i*width + j]
将一维数组用作多维数组,但您不能将多维数组视为一维数组。
It's better to use C++'s compile-time type-safety instead of just relying on not accidentally passing the wrong thing or performing the wrong reinterpret_cast. To get type-safety using raw-arrays you should use references to the raw array type you want:
最好使用 C++ 的编译时类型安全性,而不是仅仅依靠不意外地传递错误的东西或执行错误的 reinterpret_cast。要使用原始数组获得类型安全,您应该使用对所需原始数组类型的引用:
void foo(float (&f)[2][2]) {}
void foo(float (&f)[3][3]) {}
If you want to pass arrays by value you can't use raw arrays and should instead use something like std::array:
如果要按值传递数组,则不能使用原始数组,而应使用 std::array 之类的内容:
void foo(std::array<std::array<float,2>,2> f) {}
void foo(std::array<std::array<float,3>,3> f) {}
回答by Gort the Robot
This sort of casting is always cleaner, and easier to deal with, with a judicious use of typedef:
这种类型的转换总是更干净,更容易处理,明智地使用 typedef:
typedef float Matrix_t[2][2];
Matrix_t* someThingAsMatrix = (Matrix_t*) matrixReturnAsArray;
If this is C++ and not C, though, you should create a matrix class. (Or better yet, look for an open source one.)
但是,如果这是 C++ 而不是 C,则您应该创建一个矩阵类。(或者更好的是,寻找一个开源的。)