使用带有函数的指针来“返回”多维数组

时间:2015-12-17 22:00:22

标签: c++ arrays pointers multidimensional-array

我想将字符数组micPointsChar[]传递给函数initMicPoints()并将其解析为多维数组micPoints。我能够使用一维数组成功地做到这一点:

char micPointsChar[30 + 1] = {};
float *initMicPoints(char micPointsChar[], float micPoints[3]);

int main()
{
  // Read in mic points from file
    char micPointsChar[40] = "2,3.343,4.432\n";
    float micPoints[3] = {};
    float *newMicPoints = initMicPoints(micPointsChar, micPoints);
    for (int i = 1; i <= 3; i++)
    {
      Serial.print(newMicPoints[i]);
      Serial.print("\n");
    }
    return 0;
}


float *initMicPoints(char micPointsChar[], float micPoints[3])
{
  static int i = 1;
  static int micNum = 1;
  static int numMics = 1;
  float coordinateDec = 0;

  char *coordinate = strtok(micPointsChar, ",\n");
  coordinateDec = atof(coordinate);
  while (micNum <= numMics)
  {
    while (i <= ((micNum * 3)) && (coordinate != NULL))
    {
      if (i == ((micNum * 3) - 2))
      {
        micPoints[1] = coordinateDec;
      }
      else if (i == ((micNum * 3) - 1))
      {
        micPoints[2] = coordinateDec;
      }
      else if (i == ((micNum * 3) - 0))
      {
        micPoints[3] = coordinateDec;
      }
      coordinate = strtok(NULL, ",\n");
      coordinateDec = atof(coordinate);
      i++;
    }
    micNum++;
  }
  return micPoints;
}

这会输出预期的:

2.00
3.34
4.43

但是,当我更改代码以处理多维数组时,micPoints[360][3]

char micPointsChar[30 + 1] = {};
float *initMicPoints(char micPointsChar[], float micPoints[360][3]);

int main()
{
  // Read in mic points from file
    char micPointsChar[40] = "2,3.343,4.432\n";
    float micPoints[360][3] = {};
    float *newMicPoints = initMicPoints(micPointsChar, micPoints);
    static int i = 0;
    for (i = 1; i <= 3; i++)
    {
      Serial.print(*newMicPoints[i][0]);
      Serial.print("\n");
      Serial.print(*newMicPoints[i][1]);
      Serial.print("\n");
      Serial.print(*newMicPoints[i][2]);
      Serial.print("\n");
    }
    return 0;
}


float *initMicPoints(char micPointsChar[], float micPoints[360][3])
{
  static int i = 1;
  static int micNum = 1;
  static int numMics = 1;
  float coordinateDec = 0;

  char *coordinate = strtok(micPointsChar, ",\n");
  coordinateDec = atof(coordinate);
  while (micNum <= numMics)
  {
    while (i <= ((micNum * 3)) && (coordinate != NULL))
    {
      if (i == ((micNum * 3) - 2))
      {
        micPoints[i][0] = coordinateDec;
      }
      else if (i == ((micNum * 3) - 1))
      {
        micPoints[i][1] = coordinateDec;
      }
      else if (i == ((micNum * 3) - 0))
      {
        micPoints[i][2] = coordinateDec;
      }
      coordinate = strtok(NULL, ",\n");
      coordinateDec = atof(coordinate);
      i++;
    }
    micNum++;
  }
  return micPoints;
}

我收到编译时错误:

cannot convert 'float (*)[3]' to 'float*' in return

我这太复杂了吗?返回多维数组的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

首先,不幸的是

float *initMicPoints(char micPointsChar[], float micPoints[360][3])

被视为

float *initMicPoints(char* micPointsChar, float (*micPoints)[3])

您可以通过引用传递以保持大小:

float *initMicPoints(char* micPointsChar, float (&micPoints)[360][3])

然后返回micPoints

返回类型应为float (&)[360][3]float (&)[360][3]

这给了一个丑陋的

float (&initMicPoints(char* micPointsChar, float (&micPoints)[360][3]))[360][3]

并在通话现场:

float (&newMicPoints)[360][3] = initMicPoints(micPointsChar, micPoints);

首选std::arraystd::vector语法清晰。

答案 1 :(得分:0)

在这两种情况下,您只是返回参数。所以这个返回值是多余的。相反,请返回void

来避免此问题
void initMicPoints(char micPointsChar[], float micPoints[360][3])

调用代码如下所示:

float micPoints[360][3] = {};
initMicPoints(micPointsChar, micPoints);
for (int i = 1; i <= 3; i++)
{
  Serial.print(micPoints[i][0]);
  Serial.print("\n");

等。如果需要,您可以创建另一个变量float (*newMicPoints)[3] = micPoints;,但这也是多余的。

答案 2 :(得分:0)

返回数组没什么意义,因为你的函数没有构造它。你只是给调用者一个参数值的副本。

标准C库中的一些传统函数可以执行此操作,例如strcpy。我不记得上次我看到一段使用strcpy返回值的代码,它只是传入的目标指针。

// redeclare and redefine to return nothing!
void initMicPoints(char micPointsChar[], float micPoints[3]);

int main()
{
  // Read in mic points from file
    char micPointsChar[40] = "2,3.343,4.432\n";
    float micPoints[3] = {};

    initMicPoints(micPointsChar, micPoints);
    for (int i = 1; i <= 3; i++)
    {
      Serial.print(micPoints[i]); // refer to original array, now initialized
      Serial.print("\n");
    }
    return 0;
}

事实是,initMicPoints会传入传入的数组,这就是你称之为init的原因。捕获指针几乎没有用处,然后忽略范围内的原始数组。这只是将命令式代码打扮成功能性的,而没有潜在的语义。

在上面的代码中我们可以将数组转换为二维,而不会出现返回值类型问题;我们消除了它。