在C++中正确使用数组访问多个不同长度的数组的方法

4

我有几个二维数组,它们的长度各不相同:

int Array_A[][2] = {{...}, {...}, {...}, ...};
int Array_B[][2] = {{...}, {...}, ...};
int Array_C[][2] = {{...}, ...};

我需要另一个数组,使我能够访问这些数组:
??? Full_Array[] = {Array_A, Array_B, Array_C};

我应该使用什么样的???类型才是正确的?我尝试了uint**uint*但都不起作用。

如果这不可行,假设我不被允许改变Array_AArray_B等的定义,有没有一个好的方式来定义Full_Array


1
您正在尝试创建一个数组的数组的数组,因此... - Oliver Charlesworth
2
不,他们正在尝试创建一个指针数组。 - aschepler
@OliverCharlesworth 这不是一个三维数组。原始的二维数组可以任意长。 - stanleyli
我认为这个问题应该重新表述,以实际询问您的意思:您不想要这些数组的地址,而是想要访问它们的元素,因此需要一个指向这些数组(第一个)元素的指针数组。 - Daniel Jour
3个回答

7
Array_AArray_BArray_C 都是由 2 个 int 组成的数组的数组,因此它们都可以在顶层进行数组到指针的转换。所以 Full_Array 需要是由指向包含 2 个 int 的数组的指针组成的数组。声明可以写成:

```c int (*Full_Array[]) [2] = {Array_A, Array_B, Array_C}; ```
int (*FullArray[])[2] = {Array_A, Array_B, Array_C};

请注意,如果没有哨兵值,将无法确定子数组的长度。

虽然这是一个通用的有用问题(所以我不会打分),但它实际上并没有回答所提出的问题。 - Peter

1
如果数组 Array_AArray_BArray_C 的大小相同,您可以使用 & 运算符创建指向它们的指针并将它们存储在一个数组中。如果它们的大小不同,& 运算符将创建不同的指针类型,您将无法将它们存储在指针数组中。
int Array_A[3][2] = { ... };
int Array_B[3][2] = { ... };
int Array_C[3][2] = { ... };

typedef int (*PtrType)[3][2];
PtrType Full_Array[] = {&Array_A, &Array_B, &Array_C};

以下将会是一个错误。
int Array_A[][2] = { {}, {}, {} }; // Implied dimensions [3][2]
int Array_B[][2] = { {}, {} };     // Implied dimensions [2][2]
int Array_C[][2] = { {}, {}, {} }; // Implied dimensions [3][2]

typedef int (*PtrType)[3][2];
PtrType Full_Array[] = {&Array_A, &Array_B, &Array_C};

1

除了已经发布的答案外,您可能还希望考虑使用 decltype 来自动推断类型:

using PtrToArrayElem =
    decltype(&(Array_A[0]));                      // C++11, or
//  std::decay_t<decltype(Array_A)>;              // C++14 alternative, or
//  typename std::decay<decltype(Array_A)>::type; // C++11 version of above
PtrToArrayElem arrayOfPtrsToFirstElements[] = {Array_A, Array_B, Array_C};

好处是,如果您将其中一个数组的类型更改,则无需在此处更改代码。只需确保保持其余的代码(访问指针数组)也是通用的即可。


当然,如果您更喜欢将地址存储到数组本身中,这也可以工作,但前提是它们的大小相同。
using PtrToArray = decltype(&Array_A);
PtrToArray arrayOfPtrToArray[] = {&Array_A, &Array_B, &Array_C};

注意:变量名是为了解释本答案而选择的描述性名称。当然,您应该使用有意义的名称。

这样做行不通,因为每个数组的长度都可能不同。 - Brian Bi
1
@Brian 如果这些数组的长度不同,这种方法就行不通。引用问题中的话:“我需要另一个存储这些数组地址的数组”。这实际上是“正确”的答案。但是,当然,对于 OP 来说,使用数组到指针的转换可能更有意义。但这并不改变我的回答重点:如果合理,使用 decltype - Daniel Jour
我不同意,丹尼尔。OP在第一行中指出数组长度不同。换句话说,Array_A、Array_B和Array_C的第一维可能不同。如果是这种情况,它们就是不同类型的,因此指向它们的指针也是不同类型的。 - Peter
@Peter Hm,我明白了。我并没有真正注意到那一行。尽管如此,我的回答的主要观点仍然没有改变。不过,我已经编辑了它,将重点放在处理不同长度的数组上。 - Daniel Jour
1
或者 using PtrToArrayElem = std::decay_t(decltype(Array_A)); - aschepler
@aschepler 确实,已添加(使用正确的语法和C++14“警告”)。 - Daniel Jour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接