将指针解释为二维数组 [英] Interpret pointer as a two-dimensional array

查看:96
本文介绍了将指针解释为二维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组转置函数,可以像这样对数组进行镜像:

I have an array transpose function that mirrors arrays like so:

[1][2][3]            [1][4][7]
[4][5][6]    ===>    [2][5][8]
[7][8][9]            [3][6][9]

这是我提出的算法的概念:

Here is the concept of the algorithm I came up:

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 ++中的函数中实现该算法时,出现以下错误:

When proceeding through the algorithm by hand, all works as expected. I would like to implement the function such that it takes two pointers to two-dimensional arrays, one with the source array and the second to a memory buffer that will hold the transposed array. When I try to implement the algorithm in C++ in a function I get the following error:

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] = *(行+ v); 数组下标的无效类型"float [int]"

out[v][s] = *(row + v); invalid types ‘float[int]’ for array subscript

这是因为编译器不知道它应该将第二个float * out视为二维数组吗?如果是这样,解决办法是什么?

Is this because the compiler does not know that it should treat the second float * out as a 2-dimensional array? If so, what's the fix?

推荐答案

好吧,您的out变量是指向float的指针,因此在out[v]中将其取消引用会产生浮点值.而且您不能下标浮点值.

Well, your out variable is a pointer to a float, so derefencing it in out[v] yields a float value. And you can't subscript a float value.

您需要做的是计算out 2D数组的数组索引,就像计算in 2D数组的方法一样:

What you need to do, is to calculate the array index for the out 2D array the same way you calculated it for the in 2D array:

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中,您可以用一种非常不错的方式来做到这一点:


Note:
It's a pity that you are apparently writing this code in C++, and not in C. Because in C, you can do this in a quite nice way:

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];
    }
  }
}

此处的窍门是,将inout参数声明为指向行数组的指针,这允许该语言调用与使用float myArray[numvars][numsegs];声明数组时使用的指针算术魔术.该指针算法归结为隐式地执行v*numsegs + s显式地执行的相同操作.

The trick here is that the in and out arguments are declared to be pointers to line arrays, which allows the language to invoke the same pointer arithmetic magic that it uses when you declare an array with float myArray[numvars][numsegs];. This pointer arithmetic boils down to do the same thing implicitly which v*numsegs + s does explicitly.

C的优点在于,它允许具有运行时大小的数组类型,而C ++则无法做到.当然,如果numvarsnumsegs是编译时间常量,则可以在C ++中执行等效操作.

The advantage of C is, that it allows for array types with run time sizes, something C++ does not do. Of course, if numvars and numsegs are compile time constants, you can do the equivalent in C++.

如果要使用与问题中给出的签名相同的签名,可以使用以下方法编写函数:

Here is how you can write your function if you want to use the same function signature as the one you gave in the question:

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];
    }
  }
}

这篇关于将指针解释为二维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆