我有一个数组转置函数,可以像这样镜像数组:
[1][2][3] [1][4][7]
[4][5][6] ===> [2][5][8]
[7][8][9] [3][6][9]
这是我提出的算法的概念:
size_t numvars = variables.size(), numsegs = segments.size();
for (int v = 0; v < numvars; ++v) {
for (int s = 0; s < numsegs; ++s) {
float * row = in + (s * numvars);
out[v][s] = *(row + v);
}
}
当手动执行算法时,一切都按预期进行。我想实现该函数,使其需要两个指向二维数组的指针,一个指向源数组,第二个指向将保存转置数组的内存缓冲区。当我尝试在函数中用 C++ 实现该算法时,出现以下错误:
void transposeArray(float * in, float * out) throw()
{
size_t numvars = variables.size(), numsegs = segments.size();
for (int v = 0; v < numvars; ++v) {
for (int s = 0; s < numsegs; ++s) {
float * row = in + (s * numvars);
out[v][s] = *(row + v);
}
}
}
out[v][s] = *(row + v); invalid types ‘float[int]’ for array subscript
这是因为编译器不知道它应该将第二个 float * out
视为二维数组吗?如果是这样,解决办法是什么?
最佳答案
好吧,你的out
变量是一个指向 float
的指针,因此在 out[v]
中取消引用它产生一个浮点值。并且您不能为浮点值添加下标。
您需要做的是计算 out
的数组索引二维数组的计算方式与 in
的计算方式相同二维数组:
void transposeArray(float * in, float * out) throw() {
size_t numvars = variables.size(), numsegs = segments.size();
for (int v = 0; v < numvars; ++v) {
for (int s = 0; s < numsegs; ++s) {
out[v*numsegs + s] = in[s*numvars + v];
}
}
}
注意:
遗憾的是,您显然是用 C++ 编写这段代码,而不是用 C。因为在 C 中,您可以用一种非常好的方式来做到这一点:
void transposeArray(int numvars, int numsegs, float (*in)[numvars], float (*out)[numsegs]) {
for (int v = 0; v < numvars; ++v) {
for (int s = 0; s < numsegs; ++s) {
out[v][s] = in[s][v];
}
}
}
这里的技巧是in
和out
参数被声明为指向行数组的指针,这允许语言调用与使用 float myArray[numvars][numsegs];
声明数组时使用的相同的指针算术魔法。 。这个指针算术归结为隐式执行相同的操作 v*numsegs + s
明确表示。
C 的优点是,它允许具有运行时大小的数组类型,这是 C++ 所不具备的。当然,如果numvars
和numsegs
是编译时常量,您可以在 C++ 中执行等效操作。
如果您想使用与问题中给出的函数签名相同的函数签名,则可以按照以下方式编写函数:
void transposeArray(float * in, float * out) throw() {
size_t numvars = variables.size(), numsegs = segments.size();
float (*in2D)[numvars] = (void*)in;
float (*out2D)[numsegs] = (void*)out;
for (int v = 0; v < numvars; ++v) {
for (int s = 0; s < numsegs; ++s) {
out2D[v][s] = in2D[s][v];
}
}
}
关于c++ - 将指针解释为二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22287817/