/ Itération sur des tableaux multidimensionnels - c ++, tableaux

Itération sur des tableaux multidimensionnels - C ++, tableaux

Supposons que je veuille faire quelque chose pour chaque numérodans un tableau multidimensionnel. J’ai constaté que vous pouvez obtenir un pointeur pour le premier numéro, puis utiliser l’addition de pointeur. Par exemple, le code suivant affiche les numéros 1 par 12:

double a[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}};
double *p = &a[0][0][0];
for (int i = 0; i < 12; i++)
cout << *(p + i) << endl;

Est-il unidiomatique de considérer un tableau multi-dimensionnel comme étant plat de cette façon? Si oui, quelle est la manière préférée de le faire? Aussi, existe-t-il un moyen plus simple d'écrire double *p = &a[0][0][0]; pour obtenir un pointeur pour le premier nombre dans un tableau multi-dimensionnel (de la même manière que vous pouvez simplement écrire double *p = a; pour un tableau unidimensionnel)?

Réponses:

6 pour la réponse № 1

Oui, un tableau multidimensionnel est garantiappartement. Cependant, il peut être préférable d’agir de la sorte. Si vous voulez effectuer une itération à plat sur un tableau multidimensionnel, je pense qu’il serait préférable d’y introduire une vue étendue:

template <typename T>
struct Flat {
auto begin() { return first(arr); }
auto end() {
return begin() + sizeof(arr)/sizeof(*begin());
}

template <typename X> X* first(X& val) { return &val; }
template <typename X, size_t N> auto first(X(&val)[N]) { return first(*val); }

T& arr;
};

template <typename T>
Flat<T> flatten(T& arr) {
return Flat<T>{arr};
}

Et utilisez simplement celui-là:

for (double d : flatten(a)) {
std::cout << d << std::endl;
}

Sinon, la seule autre façon de déclarer p est quelque chose comme double *p = &***a; Je ne sais pas si devenir programmeur trois étoiles fait partie des priorités de votre vie.


3 pour la réponse № 2

Alors qu'il peut être très utile de savoir qu’un tableau multidimensionnel estEn fait, il serait plutôt unidiomatique de s'y référer à l'aide de pointeurs et d'arithmétique de pointeur, car il introduit plus de risque d'erreur et est plus difficile à lire que la solution idiomatique, la notation en indice. Pour cette raison, je recommanderais d'utiliser ceci:

double a[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}};

for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 2; k++)
{
cout << a[i][j][k] << endl;
}
}
}

1 pour la réponse № 3

Oui, un tableau multidimensionnel peut toujours être traité comme plat. En outre, même comme un tableau à une dimension, vous pouvez dire double *p = reinterpret_cast<double*>(a) qui est le même que double *p = &a[0][0][0].

Un tableau multidimensionnel, s'il est alloué dynamiquement, peut ne pas être plat. Mais alors ce serait évident car l’allocation sera faite par vous.