Ma première tentative de inverser pour la boucle qui fait quelque chose n fois était quelque chose comme:
for ( unsigned int i = n-1; i >= 0; i-- ) {
...
}
Ceci échoue car dans l'arithmétique non signée i
est garantie d'être toujours supérieure ou égale à zéro, d'où la la condition de boucle sera toujours vraie. Heureusement, le compilateur gcc m'a averti d'une "comparaison inutile" avant de devoir me demander pourquoi la boucle s'exécutait à l'infini.
Je cherche un moyen élégant de résoudre ce problème en gardant à l'esprit que:
Des idées? Merci :)
Que diriez-vous:
for (unsigned i = n ; i-- > 0 ; )
{
// do stuff with i
}
for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) {
unsigned int i = loopIndex - 1;
...
}
ou
for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) {
unsigned int i = n - loopIndex - 1;
...
}
for ( unsigned int i = n; i != 0; i-- ) {
// do something with i - 1
...
}
Notez que si vous utilisez C++ ainsi que C, utiliser! = Est une bonne habitude à prendre lorsque vous passez à l'utilisation d'itérateurs, où <= etc. peut ne pas être disponible.
Pourquoi pas simplement:
unsigned int i = n;
while(i--)
{
// use i
}
Cela répond à toutes les exigences énumérées dans le corps de la question. Il n'utilise aucun élément susceptible d'échouer à la révision du code ou de violer une norme de codage. La seule objection que j'ai pu y voir est que l'OP a vraiment insisté sur une boucle for
et non sur une manière simple de générer i = (n-1) .. 0.
for ( unsigned int i = n; i > 0; i-- ) {
...
i-1 //wherever you've been using i
}
J'aurais tendance à utiliser
for ( unsigned int i = n; i > 0; ) {
--i;
...
}
c'est presque la même chose que la réponse de skizz, (il manque un décrément final inutile, mais le compilateur devrait optimiser cela), et passera en fait la révision du code. Chaque norme de codage avec laquelle j'ai eu à travailler n'a eu aucune mutation dans la règle conditionnelle.
Peut-être de cette façon? À mon humble avis, son clair et lisible. Vous pouvez omettre le if (n> = 1) s'il est implicitement connu d'une manière ou d'une autre.
if(n>=1) {
// Start the loop at last index
unsigned int i = n-1;
do {
// a plus: you can use i, not i-1 here
} while( i-- != 0 );
}
Une autre version:
if(n>=1) {
unsigned int i = n;
do {
i--;
} while( i != 0 );
}
Le premier code sans instruction if ressemblerait à:
unsigned int i = n-1;
do {
} while( i-- != 0 );
for (unsigned int i = n-1; i<(unsigned int)-1; i--)
OK, son "arithmétique en anneau obscur".
Ou vous pouvez vous fier au comportement d’habillage de unsigned int
si vous avez besoin d'une indexation de n-1 à 0
for(unsigned int i = n-1; i < n; i--) {
...
}
for ( unsigned int i = n; i > 0; i-- ) {
unsigned int x = i - 1;
// do whatever you want with x
}
Certainement pas élégant, mais ça marche.
La seule raison pour laquelle je mentionne cette option est que je ne l'ai pas vue dans la liste.
for ( unsigned int i = n-1; i < n; i-- ) {
...
}
Totalement contre l'intuition, mais ça marche. la raison pour laquelle cela fonctionne est que la soustraction de 1 à 0 donne le plus grand nombre pouvant être représenté par un entier non signé.
En général, je ne pense pas que ce soit une bonne idée de travailler avec des nombres entiers et arthmétiques non signés, en particulier lors de la soustraction.
Facile, arrêtez-vous à -1:
for( unsigned int i = n; i != -1; --i )
{
/* do stuff with i */
}
edit: je ne sais pas pourquoi cela est voté. cela fonctionne et c'est plus simple et plus évident que tout ce qui précède.
for ( unsigned int i = n; i > 0; i-- ) {
...
}
Devrait bien fonctionner. Si vous devez utiliser la variable i
comme index dans un tableau, faites-le comme ceci:
array[i-1];
Hm. Voici vos options:
i=0
comme condition de rupture - La boucle ne s'exécutera pas lorsque j'atteindrai 0, exécutez donc 1 itération du contenu de la boucle pour i=0
une fois la boucle terminée.for ( unsigned int i = n-1; i > 0; i-- ) {
doStuff(i);
}
doStuff(0);
i=0
et break
out. Non recommandé car vous testez maintenant la valeur de i deux fois dans la boucle. L'utilisation de la rupture dans une boucle est également considérée comme une mauvaise pratique.for ( unsigned int i = n-1; i >= 0; i-- ) {
doStuff(i);
if (i=0) break;
}
unsigned index;
for (unsigned i=0; i<n; i++)
{
index = n-1 - i; // {i == 0..n-1} => {index == n-1..0}
}
Comme ce n'est pas une norme pour la boucle, j'utiliserais probablement une boucle while à la place, par exemple:
unsigned int i = n - 1;
while (1)
{
/* do stuff with i */
if (i == 0)
{
break;
}
i--;
}
Ceci n'est pas testé, mais pourriez-vous faire ce qui suit:
for (unsigned int i, j = 0; j < n; i = (n - ++j)) {
/* do stuff with i */
}
Utilisez deux variables, une pour compter p, et l'autre pour l'index du tableau:
unsigned int Index = MAX - 1;
unsigned int Counter;
for(Counter = 0; Counter < MAX; Counter++)
{
// Use Index
Index--;
}