web-dev-qa-db-fra.com

pause; C++: quelle boucle est-il en train de rompre?

simple question concernant le code C++: 

for(int i=0;i<npts;i++)
{
    for(int j=i;j<2*ndim;j++)
    {
        if(funcEvals[i]<bestListEval[j])
        {
            bestListEval[j] = funcEvals[i];
            for(int k=0;k<m_ndim;k++)
                bestList[j][k] = simplex[i][k]; 
            break; 
        }
    }
}

Je veux m'assurer que

  • Chaque ligne de double **simplex est insérée au plus une fois dans double **bestList
  • L'instance de break sort ici de la deuxième boucle (interne) for.

Est-ce le cas?

11
octoback

L'instruction break en C++ sortira de l'instruction for ou switch dans laquelle la rupture est directement placée. Il casse la structure la plus interne (boucle ou commutateur). Dans ce cas:

    for(int i=0;i<npts;i++)
    {
        for(int j=i;j<2*ndim;j++)
        {
            if(funcEvals[i]<bestListEval[j])
            {
                bestListEval[j] = funcEvals[i];
                for(int k=0;k<m_ndim;k++)
                    bestList[j][k] = simplex[i][k]; 
                break; 
            }
        }
        // after the 'break' you will end up here
    }

Il n’ya aucun moyen en C++ d’avoir pour cible de couper une autre boucle. Pour sortir des boucles parent, vous devez utiliser un autre mécanisme indépendant, tel que le déclenchement de la condition de fin.

En outre, si vous souhaitez quitter plusieurs boucles internes, vous pouvez extraire ces boucles dans une fonction. En C++ 11, les lambdas peuvent être utilisés pour le faire sur place - il n’y aura donc pas besoin d’utiliser goto .

31
Sergey K.

L'instruction break en C++ se démarque de l'instruction for ou switch dans laquelle la break est directement placée. Dans ce cas, il sortira de la boucle for (int j = ...

Il n'y a aucun moyen en C++ d'avoir break pour cibler une autre boucle. Pour sortir des boucles parent, vous devez utiliser un autre mécanisme indépendant, tel que le déclenchement de la condition de fin.

// Causes the next iteration of the 'for (int i ...' loop to end the loop)
i = npts;

// Ends the 'for (int j ...' loop
break;
5
JaredPar

Vous sortez de votre deuxième boucle pour votre première boucle.

for (int i=0; i<npts; i++)

Vous pouvez définir un booléen au sommet

bool shouldBreak = false;

et quand vous écrivez une pause, écrivez

shouldBreak = true;
break;

Puis à la fin de votre boucle, vérifiez à chaque fois,

if (shouldBreak) break;
4
Martol1ni

Utiliser break

break sortira de la boucle répétée ou itérative dans laquelle elle se trouve actuellement. Ce guide d'images détaillé est destiné à mettre en évidence le comportement de break et non à illustrer de bonnes pratiques de codage. L'intérieur de la boucle aurait suffi, mais comme je l'ai dit, c'est à des fins visuelles:

 double-iterating-loops

Conseil alternatif

Utilisez les divers algorithmes de recherche de Modern C++ disponibles dans <algorithm> pour effectuer une recherche dans les conteneurs et, dans une certaine mesure, dans les chaînes. La raison en est double:

  1. Code plus court et plus facile à lire 
  2. Habituellement aussi vite sinon plus que tout ce que vous auriez pu écrire vous-même 

Ces échantillons de code auront besoin de la même plaque chaudière, à l'exception de <algorithm> pour les recherches plus anciennes avec boucle:

#include <vector>
#include <algorithm>

std::vector<int> int_container = { 10, 23, 10345, 432, 2356, 999, 1234, 0x45f };
bool has1234 = false;

La manière moderne serait quelque chose comme ceci, où nous cherchons rapidement dans le conteneur et si le chercheur-itérateur n'est pas à la toute fin du conteneur (pas le dernier élément ), nous savons que la valeur recherchée a été localisée .

Ce code produit le même résultat avec moins de lignes et moins de points de défaillance potentiels pour le code écrit par l'utilisateur, à l'instar des anciennes solutions plus basses.

Style C++ moderne

auto search_position = std::find( int_container.begin(), int_container.end(), 1234 ) ;
if ( search_position != int_container.end() )
    has1234 = true;

Boucle for C++ 11 basée sur la plage

for ( auto i : int_container )
{
    if ( i == 1234 )
    {
        has1234 = true;
        break;
    }
}

C-style à l'ancienne pour la boucle:

for ( int i = 0; i < int_container.size(); i++ )
{
    if ( int_container[i] == 1234 )
    {
        has1234 = true;
        break;
    }
}
1
kayleeFrye_onDeck
for (int i = 0; i < npts; i++)

Vous pouvez définir un booléen au sommet

bool shouldBreak = false;

et quand vous voulez casser l'autre boucle, écrivez

shouldBreak = true;
break;
1

Si vous n'avez pas de parenthèses après if/else/while/for, seule la première ligne suivant if/else/for/while sera exécutée, ainsi la boucle suivante:

for(int k=0;k<m_ndim;k++)

ne ferait que boucler la ligne suivante:

 bestList[j][k] = simplex[i][k];

ainsi, la déclaration break après les divisions ne l’affectera en aucune manière. Si vous considérez que break; est utilisé pour rompre les boucles et les instructions switch, l'instruction break serait appliquée à:

for(int j=i;j<2*ndim;j++)
0
Gox