【问题标题】:Functions to Handle Multi-dimensional Arrays of Different Sizes处理不同大小的多维数组的函数
【发布时间】:2015-03-06 22:29:20
【问题描述】:

长话短说,我正在尝试为各种事物处理一些数组。在调试期间,我需要打印数组。我只想有一个函数来打印传递给它的任何数组。我也可以相当容易地传递数组的维度。现在让我们假设,我只使用一个二维数组。
相信我;我已经审查了这里提出的所有类似问题,并试图实施建议的解决方案,但无济于事。我尝试过使用指针等。特别是,我在这篇文章中尝试了所有四种解决方案: https://stackoverflow.com/a/17569578/4641918,根据方法的不同,我仍然会遇到无数错误。 我对编程并不陌生,但我对 C++ 很陌生。 这是我正在尝试做的一个非常简化的示例:

//  Array Failures
#define FIRSTWIDTH 6        //Number of Columns in First Array
#define FIRSTHEIGHT 5       //Number of Rows in First Array
#define SECONDWIDTH 4       //Number of Columns in Second Array
#define SECONDHEIGHT 2      //Number of Rows in Second Array


//  An couple of arrays are declared with dimensions WIDTH X HEIGHT
int firstArray[FIRSTWIDTH][FIRSTHEIGHT];
int secondArray[SECONDWIDTH][SECONDHEIGHT];

void setup()
{
Serial.begin(57600);
fillXXArray(FIRSTWIDTH, FIRSTHEIGHT, firstArray);
fillXXArray(SECONDWIDTH, SECONDHEIGHT, secondArray);  //GENERATES ERROR 1
Serial.println("Program Initialized");
printANYArray(FIRSTWIDTH, FIRSTHEIGHT, firstArray); 
}

void loop(){return;}

void fillXXArray(int width, int height, int myArray[][FIRSTHEIGHT]){
// Fills an array with values that is WIDTH X HEIGHT
// Inner Subset is the sum of its coordinates
for (int w = 0; w < width - 1; w++){
    for (int h = 0; h < height - 1; h++){
        myArray[w][h] = w + h;
    }
}

// Loop across the bottom row and set them to the sum of the column.
for (int w = 0; w < width - 1; w++){
    for (int h = 0; h < height - 1; h++){
        myArray[w][height - 1] = myArray[w][height - 1] + myArray[w][h];
    }
 }

// Loop down the last column and set it to the product of the values in row.
for (int h = 0; h < height - 1; h++){
    myArray[width - 1][h] = myArray[0][h];
    for (int w = 1; w < width - 1; w++){
        myArray[width-1][h] = myArray[width-1][h] * myArray[w][h];
    }
}
myArray[width - 1][height - 1] = width * height;

//  The final array is populated like this.
//
//            0     1     2    ...         w
//    0    [  0     1     2    ...   (Product of Row)  ]
//    1    |  1     2     3    ...   (Product of Row)  |
//    2    |  2     3     4    ...   (Product of Row)  |
//   ...   | ...   ...   ...   ...   (Product or ...)  |
//    h    [(Sum) (Sum) (Sum)  ...       (h*W)         ]
//
}

void printANYArray(size_t width, size_t height, int myArray[][height]){  //GENERATES ERROR 2
Serial.println("printXXArray: ");
for (int h = 0; h < height; h++){
    for (int w = 0; w < width; w++){
        Serial.print(myArray[w][h]); Serial.print("\t\t");
    } Serial.println();
} Serial.println();
}

错误 1:(VS2013 突出显示“secondArray”)错误:“int()[2]”类型的参数与“int()[5]”类型的参数不兼容。这很明显,因此我试图避免。所以我从函数定义中删除了常量,得到了第二个错误。

错误2::“高度”突出显示)错误:不允许使用参数。

主要解决方案结束。

下一个解决方案:将数组作为指针传递。 我将函数声明更改为:

void printANYArray(size_t width, size_t height, int **myArray){

但它没有在函数中引发标志,但函数调用失败:

 printANYArray(FIRSTWIDTH, FIRSTHEIGHT, firstArray);

“firstArray”错误:“int(8)[5]”类型的参数与“int **”类型的参数不兼容

下一个解决方案:“该函数正在使用指针,所以我不应该向它发送地址吗?”我将函数调用更改为:

printANYArray(FIRSTWIDTH, FIRSTHEIGHT, &firstArray);

只有“&”被突出显示,错误:“int (*)[6][5]”类型的参数与“int **”类型的参数不兼容 等等……什么?!?我以为我只是发送地址。

下一个猜测('因为这就是我现在正在做的事情): 我删除了声明中的 * 之一。这只是从错误消息中删除了一颗星。好吧,至少这是可以理解的。

所以...您可以提供的任何帮助都会有所帮助。同样,这适用于可能与它有关的 Arduino,因为我似乎无法从示例中获得任何解决方案来工作——即使我复制并粘贴了整个源代码。

【问题讨论】:

  • template &lt;size_t M, size_t N&gt; void fillXXArray(int (&amp;myArray)[M][N]);

标签: arrays pointers visual-c++ multidimensional-array arduino


【解决方案1】:

我会避免使用模板,因为在 Arduino 上你想保留 编译代码小。我会改为使用旧式一维数组:

int firstArray[FIRSTHEIGHT * FIRSTWIDTH];
int secondArray[SECONDHEIGHT * SECONDWIDTH];

C 语言家族中通常的约定是存储矩阵 按行,并使第一个索引成为行索引。按照这个 按照惯例,行 ij 的单元格将是 arr[i][j] “真实”二维数组,arr[width * i + j] 用于这些“伪造”二维数组。 以下是您填写它们的方法:

void fillXXArray(int *myArray, int height, int width) {

    // Inner Subset is the sum of its coordinates
    for (int h = 0; h < height - 1; h++) {
        for (int w = 0; w < width - 1; w++) {
            myArray[width * h + w] = h + w;
        }
    }

    // Bottom row has the sums of the columns.
    for (int w = 0; w < width - 1; w++) {
        myArray[width * (height - 1) + w] = 0;
        for (int h = 0; h < height - 1; h++) {
            myArray[width * (height - 1) + w] += myArray[width * h + w];
        }
     }

    // Last column has the product of the rows.
    for (int h = 0; h < height - 1; h++) {
        myArray[width * h + (width - 1)] = myArray[width * h + 0];
        for (int w = 1; w < width - 1; w++) {
            myArray[width * h + (width - 1)] *= myArray[width * h + w];
        }
    }

    // Last cell.
    myArray[width * (height - 1) + (width - 1)] = width * height;
}

我冒昧地将数组作为第一个参数。这是 非正式约定:每当您将指针与大小一起传递时 信息,指针一般先出现。参考文献snprintf() 和 以strncpy() 为例。

如果您不介意额外的内存成本,那么您可以使用额外的 用于存储每一行​​的起始地址的指针数组。这边走 您可以使用更简单的语法arr[i][j] 访问数组元素, 其中arr 现在是辅助数组。这通常会完成 通过构造函数中的动态分配,但是由于您的数据就是全部 静态的,我们可以避免动态分配:

int firstArrayData[FIRSTHEIGHT * FIRSTWIDTH];       // actual data
int *firstArray[FIRSTHEIGHT] = { firstArrayData };  // pointers to rows

这里,只有firstArray[]的第一个指针被正确初始化。 您必须在运行时初始化其余部分,例如在 fillXXArray():

void fillXXArray(int **myArray, int height, int width) {

    // Initialize the pointers to the start of the rows.
    for (int h = 1; h < height; h++) {
        myArray[h] = myArray[0] + width * h;
    }

    // Inner Subset is the sum of its coordinates
    for (int h = 0; h < height - 1; h++) {
        for (int w = 0; w < width - 1; w++) {
            myArray[h][w] = h + w;      // <-- syntax like 2D arrays
        }
    }

    // etc...

【讨论】:

  • 非常感谢埃德加。不是我所希望的,但这肯定会奏效!感谢您的彻底回复!
猜你喜欢
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2011-05-26
相关资源
最近更新 更多