簡體   English   中英

使用帶有函數的指針來“返回”多維數組

[英]Using pointers with functions to “return” multidimensional arrays

我想將字符數組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

我讓這個變得太復雜了嗎? 返回多維數組的最佳方法是什么?

首先,不幸的是

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

在這兩種情況下,您都只是返回參數。 因此,此返回值是多余的。 而是通過返回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; 如果您願意,但這也將是多余的。

返回數組毫無意義,因為您的函數尚未構造它。 您只是給調用者一個參數值的副本。

標准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 捕獲指針然后忽略范圍內的原始數組幾乎沒有用。 那只是修飾命令性代碼以使其看起來有效,而沒有底層語義。

在上面的代碼中,我們可以將數組變成二維的,而不會出現返回值類型問題。 我們消除了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM