web-dev-qa-db-de.com

brechen; C++: In welcher Schleife bricht es eigentlich?

einfache Frage zu C++ - Code: 

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; 
        }
    }
}

Ich möchte das sicherstellen

  • Jede Zeile von double **simplex wird höchstens einmal in double **bestList eingefügt.
  • Die Instanz von break bricht hier aus der zweiten (inneren) for-Schleife aus.

Ist das der Fall?

11
octoback

Die break-Anweisung in C++ bricht die for- oder switch-Anweisung aus, in der der break direkt platziert wird. Es zerstört die innerste Struktur (Schleife oder Schalter). In diesem Fall:

    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
    }

In C++ gibt es keine Möglichkeit, break eine andere Schleife zu verwenden. Um die Elternschleifen zu durchbrechen, müssen Sie einen anderen unabhängigen Mechanismus verwenden, z. B. das Auslösen der Endebedingung.

Wenn Sie mehr als eine innere Schleife beenden möchten, können Sie diese Schleifen in eine Funktion extrahieren. In C++ 11 können Lambdas direkt vor Ort verwendet werden, sodass Sie goto nicht verwenden müssen.

31
Sergey K.

Die break-Anweisung in C++ bricht aus der for- oder switch-Anweisung, in der die break direkt platziert ist. In diesem Fall bricht die for (int j = ...-Schleife aus. 

In C++ gibt es keine Möglichkeit, break auf eine andere Schleife zu richten. Um die Elternschleifen zu durchbrechen, müssen Sie einen anderen unabhängigen Mechanismus verwenden, z. B. das Auslösen der Endebedingung.

// 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

Sie brechen aus Ihrer zweiten Schleife zu Ihrer ersten Schleife aus.

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

Sie könnten oben einen Booleschen Wert setzen

bool shouldBreak = false;

und wenn Sie break schreiben, schreiben Sie

shouldBreak = true;
break;

Prüfen Sie dann am Ende Ihrer Schleife jedes Mal:

if (shouldBreak) break;
4
Martol1ni

break verwenden

break wird aus der Wiederholungs- oder Wiederholungsschleife ausbrechen, in der sie sich gerade befindet. Dieser ausführliche Bildleitfaden soll das Verhalten von break hervorheben und keine guten Kodierungsverfahren veranschaulichen. Die innere for-Schleife hätte ausgereicht, aber wie gesagt, dies ist aus visuellen Gründen:

 double-iterating-loops

Alternative Beratung

Verwenden Sie die verschiedenen in <algorithm> verfügbaren Suchalgorithmen von Modern C++, um Container und in gewissem Maße Strings zu durchsuchen. Der Grund dafür ist zweifach:

  1. Kürzerer und leichter lesbarer Code 
  2. Normalerweise genauso schnell, wenn nicht schneller als alles, was Sie selbst geschrieben haben könnten 

Diese Codebeispiele benötigen dieselbe Boiler-Platte, außer <algorithm> für die ältere for-loop-Suche:

#include <vector>
#include <algorithm>

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

Der moderne Weg wäre etwa so, dass wir schnell den Container durchsuchen und wenn der Such-Iterator nicht ganz am Ende des Containers ist (nicht das letzte Element ), wir wissen, dass der Wert, nach dem gesucht wurde, gefunden wurde .

Dieser Code erzielt das gleiche Ergebnis mit weniger Zeilen und weniger potenziellen Ausfallpunkten für vom Benutzer geschriebenen Code, wie die älteren Alternativen darunter.

Moderner C++ - Stil

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

For-loop für den C++ 11-Bereich

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

Old-School-C-Stil für die Schleife:

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

Sie könnten oben einen Booleschen Wert setzen

bool shouldBreak = false;

und wenn Sie die andere Schleife unterbrechen möchten, schreiben Sie

shouldBreak = true;
break;
1

Wenn Sie nach if/else/while/for keine Klammern haben, wird nur die erste Zeile nach if/else/for/while ausgeführt, also folgende Schleife:

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

würde nur die folgende Zeile durchlaufen:

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

daher würde die break-Anweisung nach den Stationen dies in keiner Weise beeinflussen. Wenn Sie bedenken, dass break; verwendet wird, um Schleifen auszubrechen und Anweisungen zu wechseln, würde die break-Anweisung auf Folgendes angewendet:

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