我知道这行得通。
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};
必须做什么才能制作不同元素大小的数组数组?
我计划使用单独的变量跟踪每个数组大小。
我相信最兼容的方法是使用struct
(或class
)来描述数组:
struct Array_Attributes
{
int8_t * array_memory;
unsigned int maximum_rows;
unsigned int maximum_columns;
};
您可以通过从 2d 索引转换为 1d 索引将array_memory
视为多维数组:
unsigned index = row * maximum_columns + column;
你也可以用链表创建一个数组。 这将允许不同尺寸的尺寸。
+-------+ +----------+ +----------+
| row 0 | --> | column 0 | --> | column 1 | ...
+-------+ +----------+ +----------+
|
|
V
+-------+ +----------+ +----------+
| row 1 | --> | column 0 | --> | column 1 | ...
+-------+ +----------+ +----------+
"请停下来观想一下," 记忆"实际上是什么样子的。
显然,arrayOf2DArrays2
由:"三个指针的数组"组成。
内容可以预测这三个元素中的每一个组成,我们可以非常清楚地看到它们三个都是不同的。 "可是,C++...不能!(因为:到目前为止,您还没有提供任何手段来这样做。
因此,您现在需要利用C++的"容器类"。
arrayOf2DArrays2
应该由"一个容器"组成,目前包含(三个)其他"容器",每个容器都能够告诉您它包含多少元素,并且在您尝试访问不包含的元素时也会引发运行时异常。
当你这样做时,一个"简单"的陈述,如arrayOf2DArrays2[x][y]
(或你有什么......)将被C++"自动"理解为指代一系列实际上复杂的事件:首先,将要求外部容器解析[x]
,然后要求因此引用的内部容器解析[y]
。
好的,我也想回答我自己的问题。这里有很多好主意,但让我发布这个简单且内存成本低的解决方案。对于内存最小的设备(例如:具有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
。