如何制作宽度不同的2D数组?

时间:2016-07-06 23:54:09

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

我知道这很有用。

int8_t intArray7[][2] = {-2, -1,
                          0, 1,
                          2, 3,
                          4, 5,
                          6, 7};

int8_t intArray8[][2] = {10, 9,
                          8, 7,
                          6, 5,
                          4, 3,
                          2, 1, 
                          0, -1,
                         -2, -3};

int8_t intArray9[][2] = {100, 101,
                         102, 103};

int8_t (*arrayOf2DArrays[])[2] = {intArray7, intArray8, intArray9};

现在,如果2D阵列的宽度不同,该怎么办?我该如何做到这一点?

例如:这不起作用,因为intArray11是宽度3:

 int8_t intArray10[][2] = {-2, -1,
                            0, 1,
                            2, 3,
                            4, 5,
                            6, 7};

int8_t intArray11[][3] = {10, 9, 8,
                           7, 6, 5, 
                           4, 3, 2,
                           1, 0, -1};

int8_t intArray12[][2] = {100, 101,
                          102, 103};

int8_t (*arrayOf2DArrays2[])[] = {intArray10, intArray11, intArray12};

必须做些什么来制作不同元素大小的数组?

我计划使用单独的变量跟踪每个数组大小。

3 个答案:

答案 0 :(得分:1)

我认为最兼容的方法是使用struct(或class)来描述数组:

struct Array_Attributes
{
  int8_t * array_memory;
  unsigned int maximum_rows;
  unsigned int maximum_columns;
};

您可以将array_memory视为多维数组,方法是将2d转换为1d:

unsigned index = row * maximum_columns + column;

你也可以用链表制作一个数组。这将允许不同尺寸的尺寸。

+-------+     +----------+     +----------+  
| row 0 | --> | column 0 | --> | column 1 | ...  
+-------+     +----------+     +----------+  
    |  
    |
    V  
+-------+     +----------+     +----------+  
| row 1 | --> | column 0 | --> | column 1 | ...  
+-------+     +----------+     +----------+  

答案 1 :(得分:0)

"暂时停下来想象一下" " 内存" 实际上是什么样子。 。 。

显然,

arrayOf2DArrays2包含:"三个指针的数组。"

不幸的是,对于你来说,任何一个都没有来预测这三个元素中的每一个,我们可以非常清楚地看到他们三个都是不同的。 "但是, C ++ ... 不能!" (因为:你迄今为止没有提供任何手段这样做。)

因此,您现在需要利用C ++的"容器类。"

arrayOf2DArrays2 应该由"一个容器组成,"目前包含(三个)其他"容器," ,每个容器都能告诉你包含多少元素,以及抛出一个如果您尝试访问 it 不包含的元素,则运行时异常。

当你这样做时,一个简单的"诸如arrayOf2DArrays2[x][y] (或者你有什么......)这样的陈述将会自动地#34;被C ++理解为指的是一系列实际复杂的事件:首先,外部容器将被要求解析[x]然后因此 - 引用内部容器将被要求解析[y]

答案 2 :(得分:0)

好吧,我也想回答我自己的问题。这里有很多好主意,但让我发布这个简单且内存成本低的解决方案。对于最小内存的设备(例如:具有512字节RAM和几KB程序闪存的ATTiny AVR微控制器),我认为这可能是最佳解决方案。我测试了它;有用。使用指向int8_t的指针数组 - 即:指向1D数组的指针数组,如下所示:

int8_t intArray10[][2] = {-2, -1,
                            0, 1,
                            2, 3,
                            4, 5,
                            6, 7};

int8_t intArray11[][3] = {10, 9, 8,
                           7, 6, 5, 
                           4, 3, 2,
                           1, 0, -1};

int8_t intArray12[][2] = {100, 101,
                          102, 103};

//get some array specs we need about the arrays
byte arrayLengths[] = {sizeof(intArray10)/sizeof(int8_t), sizeof(intArray11)/sizeof(int8_t), 
                        sizeof(intArray12)/sizeof(int8_t)}; //redundant division since int8_t is 1 byte, but I want to leave it for verboseness and extension to other types 
byte arrayCols[] = {2, 3, 2};

//make pointers to int8_t's and point each pointer to the first element of each 2D array, as though each 2D array was a 1D array
//-this works because the arrays use contiguous memory 
int8_t *intArray10_p = &(intArray10[0][0]); 
int8_t *intArray11_p = &(intArray11[0][0]);
int8_t *intArray12_p = &(intArray12[0][0]);

//make an array of those pointers to 1D arrays 
int8_t *intArrayOfnDimArray[] = {intArray10_p, intArray11_p, intArray12_p};

//print the 3 arrays via pointers to (contiguous) 1D arrays:
//-Note: this concept and technique should work with ANY contiguous array of ANY number of dimensions
for (byte i=0; i<sizeof(intArrayOfnDimArray)/sizeof(intArrayOfnDimArray[0]); i++) //for each 2D array 
{
  for (byte j=0; j<arrayLengths[i]; j++) //for all elements of each 2D array 
  {
    Serial.print(intArrayOfnDimArray[i][j]); Serial.print("/"); //now read out the 2D array values (which are contiguous in memory) one at a time; STANDARD ARRAY ACCESS TECHNIQUE 
    Serial.print(*(intArrayOfnDimArray[i] + j)); Serial.print("/"); //ARRAY/POINTER TECHNIQUE (extra teaching moment)
    Serial.print((*(intArrayOfnDimArray + i))[j]); Serial.print("/"); //POINTER/ARRAY TECHNIQUE
    Serial.print(*(*(intArrayOfnDimArray + i) + j)); //POINTER/POINTER TECHNIQUE 

    //add a comma after every element except the last one on each row, to present it in 2D array form 
    static byte colCount = 0; //initialize as being on "Column 1" (0-indexed)
    if (colCount != arrayCols[i]-1) //if not on the last column number 
      Serial.print(", ");
    else //colCount==arrayCols[i]-1 //if we *are* on the last column number 
      Serial.println();
    colCount++;
    if (colCount==arrayCols[i])
      colCount = 0; //reset 
  }
  Serial.println(F("-----")); //spacer 
}

输出:

-2/-2/-2/-2, -1/-1/-1/-1
0/0/0/0, 1/1/1/1
2/2/2/2, 3/3/3/3
4/4/4/4, 5/5/5/5
6/6/6/6, 7/7/7/7
-----
10/10/10/10, 9/9/9/9, 8/8/8/8
7/7/7/7, 6/6/6/6, 5/5/5/5
4/4/4/4, 3/3/3/3, 2/2/2/2
1/1/1/1, 0/0/0/0, -1/-1/-1/-1
-----
100/100/100/100, 101/101/101/101
102/102/102/102, 103/103/103/103
-----

注意:正如Thomas Matthews在他的回答中教导的那样,要访问特定的2D数组,行和列,请使用以下内容:

byte index = row * maximum_columns + column;

在上面的示例中将是:

byte rowColIndex = desiredRow * arrayCols[desired2DArrayIndex] + desiredColumn;
int8_t val = intArrayOfnDimArray[desired2DArrayIndex][rowColIndex];

注意:byte相当于uint8_t