• 1
  • 2
2022-07-24, 21:25
  #13
Medlem
Som Enterprise tipsar om så kapslar du in de slingor du redan har i ännu en slinga, så att koden blir ungefär så här:

Kod:
villSpela=true;
while(villSpela==true)
{
  while(villkor för slinga ett)
 {.
  .
  .
  .
 }   // slut på dina ursprungliga slingor

fråga "Vill du spela igen?"
inmatning->villSpela
}  // slut på omgivande slingan
return();
Sedan måste du se till att alla variabler som påverkas under spelets gång har rätt värden när yttre slingan upprepas. En del variabler kan behöva initieras utanför slingan, och andra innanför.
__________________
Senast redigerad av xpqr12345 2022-07-24 kl. 21:47. Anledning: stavfel
Citera
2022-07-25, 11:24
  #14
Medlem
Citat:
Ursprungligen postat av xpqr12345
Som Enterprise tipsar om så kapslar du in de slingor du redan har i ännu en slinga, så att koden blir ungefär så här:

Kod:
villSpela=true;
while(villSpela==true)
{
  while(villkor för slinga ett)
 {.
  .
  .
  .
 }   // slut på dina ursprungliga slingor

fråga "Vill du spela igen?"
inmatning->villSpela
}  // slut på omgivande slingan
return();

Sedan måste du se till att alla variabler som påverkas under spelets gång har rätt värden när yttre slingan upprepas. En del variabler kan behöva initieras utanför slingan, och andra innanför.

Kortfattat och bra, bra där !!!
Citera
2022-07-25, 14:38
  #15
Medlem
JohannesSnajdares avatar
Citat:
Ursprungligen postat av NegerStryparen
Tycker dock att exception som betyder undantag ska verkligen vara ett undantag,
alltså något exceptionellt har hänt.
Och i de flesta fall innebär att programmet termineras direkt.

Om man hoppar tillbaks till de tidiga specs för C++ så var en exception något som är betydligt mera användbart än C 's globala variabel errno.
En exception ska i C++ bland annat göra viss uppstädning, dvs deallokera lokala variabler,
och "unwinda" scopet för en del andra variabler,
plus till exempel att anropa destruktorerna för allokerade objekt mm.

Errno i C hade alltså den typiska nackdelen att man inte kunde städa upp efter sig ordentligt.
Vilket för vissa program kunde bli problematiskt genom att filer inte stängdes korrekt eller tex redirection av filerna inte fungerade. Till exempel stdin , stdout, stdprn, stddbg med flera...

En exception är inget som hör till normal programbyggnad. Man brukar istället om man har flera loopar inne i varandra använda olika flaggor, tex en flagga för varje loop. En flagga är en bool och
som är antingen false eller true.

TS syntax är fel, man skriver inte
while i=deposit:
utan
while (i == deposit)

Tja, allt beror väl på omständigheterna och vad som anses "normalt" resp. "undantag".

Jag kan hålla med om att exceptions normalt inte ska ersätta vanlig flödeskontroll if/else, while/for et.c. men de _kan_ vara smidiga att ta till just för fallet där man vill avbryta nuvarande exekvering och börja om (eller ta sig ur) oavsett hur långt ner man nästlat sig.

Ta följande pseudokod som innehåller tre nästlade for-loopar och där man i den innersta av någon anledning vill avbryta i den 6:e iterationen och starta om på nytt. Det kan såklart göras genom en "restart"-flagga som sen måste kollas efter varje loop.

Funkar väl i såhär enkel kod men det är lätt hänt att det blir logiska fel när/om koden blir större och mer komplicerad. Också lätt hänt att ny kod läggs till efter loopen men innan if( restart ) vilket gör att koden körs även om restart är satt - kanske inte vad man avsåg...

Kod:
while( true ) {
bool restart = false;

    for(a=0; a<10; a++) {

        for(b=0; b<10; b++) {

             for(c=0; c<10; c++) {

                 if( c==5 ) {

                     restart = true;
                     break;            
                 }

             }
   
             if( restart )
                 break;

             // ev kod här ska INTE köras vid restart
       }

       if( restart )
           break;

        // ev kod här ska INTE köras vid restart
    }
}


Med exceptions skulle det se ut såhär:

Kod:
struct RestartException : public exception {}

while( true ) {

    try {
        for(a=0; a<10; a++) {

            for(b=0; b<10; b++) {

                 for(c=0; c<10; c++) {

                     if( c==5 ) {
                         throw new RestartException();
                     }
                 }
   
                 // ev kod här ska INTE köras vid restart
           }

           // ev kod här ska INTE köras vid restart
      }
      catch(RestartException& rex) {}
}


__________________
Senast redigerad av JohannesSnajdare 2022-07-25 kl. 14:51.
Citera
2022-07-25, 14:49
  #16
Medlem
JohannesSnajdares avatar
Det blir sen ännu knöligare om man vill refaktorera och flytta ut B-loopen till en egen funktion, då finns ju inte restart-variabelen i scope och måste då skickas med till funktionen:

Kod:
function B_loop(bool& restart) {

        for(b=0; b<10; b++) {

             for(c=0; c<10; c++) {

                 if( c==5 ) {

                     restart = true;
                     break;            
                 }

             }
   
             if( restart )
                 break;

             // ev kod här ska INTE köras vid restart
       }
}

while( true ) {
    bool restart = false;

    for(a=0; a<10; a++) {

       B_loop(restart);

       if( restart )
           break;

        // ev kod här ska INTE köras vid restart
    }
}

Något man inte behöver fundera över om man använder exceptions:

Kod:
struct RestartException : public exception {}

function B_loop() {

    for(b=0; b<10; b++) {

        for(c=0; c<10; c++) {

            if( c==5 ) {
                throw new RestartException();
            }
        }
    }
}

while( true ) {

    try {
        for(a=0; a<10; a++) {
           B_loop();
        }

        // ev kod här ska INTE köras vid restart
      }
      catch(RestartException& rex) {}
}
__________________
Senast redigerad av JohannesSnajdare 2022-07-25 kl. 14:55.
Citera
2022-07-25, 20:39
  #17
Medlem
Citat:
Ursprungligen postat av JohannesSnajdare
Det blir sen ännu knöligare om man vill refaktorera och flytta ut B-loopen till en egen funktion, då finns ju inte restart-variabelen i scope och måste då skickas med till funktionen:

Kod:
function B_loop(bool& restart) {

        for(b=0; b<10; b++) {

             for(c=0; c<10; c++) {

                 if( c==5 ) {

                     restart = true;
                     break;            
                 }

             }
   
             if( restart )
                 break;

             // ev kod här ska INTE köras vid restart
       }
}

while( true ) {
    bool restart = false;

    for(a=0; a<10; a++) {

       B_loop(restart);

       if( restart )
           break;

        // ev kod här ska INTE köras vid restart
    }
}

Något man inte behöver fundera över om man använder exceptions:

Kod:
struct RestartException : public exception {}

function B_loop() {

    for(b=0; b<10; b++) {

        for(c=0; c<10; c++) {

            if( c==5 ) {
                throw new RestartException();
            }
        }
    }
}

while( true ) {

    try {
        for(a=0; a<10; a++) {
           B_loop();
        }

        // ev kod här ska INTE köras vid restart
      }
      catch(RestartException& rex) {}
}

Mycket bra exempel i de två inläggen, nu ids jag inte sätta upp och köra dem, men visst. Rätt använt så är exceptions ibland mycket värdefulla. Hittade dock exempel på programvara där kritik uttrycktes på att exceptions ibland kunde göra det svårt att backtracea vad som innan exceptionen kastades.
Vet inte om det är fixat i nyare versioner.

Tycker själv att man ska utnyttja att skicka med en förklarande sträng med exception objektet. Exceptions är bra på det viset att de städar upp scope-kopplingar osv, plus ska anropa destruktors i rätt ordning.

Men denna pseudodiskussion kanske förvirrar vad TS vill uppnå ?
Och att TS kunde var lite tydligare med vad som ska åstadkommas
nu ?
Kanske någon är bättre här att skriva pedagogiskt ?
Citera
  • 1
  • 2

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in