Przerwanie pętli for przy z wnętrza switch

0

Algorytm odczytuje zawartość wierszy w dwuwymiarowej tablicy (ot, taki typowy scanline). Na podstawie odczytanych informacji wykonuje określone operacje. Chciałbym, aby jedną z nich było przerwanie dalszego odczytywania danego wiersza i przeskok do następnego. Mam taki kod:

for (int Y = 0; Y < 100; Y++)
{
    for (int X = 0; X < 250; X++)
    {
        switch(GeStatus(X, Y)) //zwraca inta
        {
        case 0:
            //cośtam
            break;
        case 1:
            //cośtam
            break;
        }
    }
}

Czy da się zrobić tak, by jeden z case'ów mógł przerwać pętlę (X) i przeskoczyć do następnego wiersza (Y + 1), czy też muszę wywalić switcha i załatwić to np. ifami? A może warto wykorzystać goto?

1

Nie wiem co gorsze. To, czy goto.

for (int Y = 0; Y < 100; Y++)
{
    for (int X = 0; X < 250; X++)
    {
        bool jumpToOuterLoop = false;
        switch(GeStatus(X, Y)) //zwraca inta
        {
        case 0:
            //cośtam
            break;
        case 1:
            jumpToOuterLoop = true;
            break;
        }
        if(jumpToOuterLoop) break;
    }
}
1

A jakbyś to przerefaktorował na dwie funkcje?

void scan_line(int Y) {
    for (int X = 0; X < 250; X++) {
        switch(GeStatus(X, Y)) {
        case 0:
            return; // przerwij
        case 1:
            //cośtam
            break;
        // ...
        }
    }
}

void scan_all() {
    for (int Y = 0; Y < 100; Y++) {
        scan_line(Y);
    }
}
0

W zalinkowanym przez @Spearhead wątku sugerują trzy rozwiązania:

  1. goto
  2. Rozbicie na osobne funkcje
  3. Warunek sprawdzający zakończenie pętli, aktywowany z poziomu switcha (to co sugerował @urke)

Zależy mi na szybkości, więc chyba wybiorę nr 1, ewentualnie 2 + inline. goto jest chyba najbardziej intuicyjnym rozwiązaniem, ale jak człowiek się naczyta, że użycie goto w C++ jest fuszerką i oznaką złego programisty itd., to potem woli tego za wszelką cenę unikać, mimo że w zasadzie rozwiązuje to problem i chyba żadnych szkód w kodzie nie zrobi ;).

Tak czy inaczej dzięki za sugestie!

3

Ja bym zrobił to jak urke tylko bym już tego ifa nie pisał ,tylko dodał do warunku pętli.

for (int Y = 0; Y < 100; ++Y)
{
    bool jumpToOuterLoop = false;
    for (int X = 0; X < 250 && !jumpToOuterLoop; ++X)
    {
        switch(GeStatus(X, Y)) //zwraca inta
        {
        case 0:
            //cośtam
            break;
        case 1:
            jumpToOuterLoop = true;
            break;
        }
    }
}

Tylko w zależności co będzie się zdarzało częściej musisz to dać pierwsze w warunku pętli.

2

IMHO dobrym rozwiązaniem jest użycie lambdy. Warto zaznaczyć, że użycie jej nie musi wiązać się z żadnym dodatkowym wywołaniem funkcji, gdyż kompilator potrafi potraktować je jako funkcje inline, rozwijając ich kod w miejscu wywołania.

#include <iostream>

using namespace std;

inline int GetStatus( int x , int y ){ return x==2?1:0; };

int main()
{

    for( int Y {0} ; Y<100 ; ++Y )
    {
        [&]()
        {
            for( int X {0} ; X<250 ; ++X )
            {
                switch( GetStatus(X,Y) )
                {
                  case 0:
                    cout << "Status 0 for X = " << X << " , Y = " << Y << "\n";
                  break;
                  case 1:
                    return; // exit
                  break;
                }
            }
         }();
    }

    return 0;
}
0

Po prostu przerób drugiego fora na while i tam ustaw odpowiednie warunki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1