Mit break aus for(..;..;..) raus?



  • Apollon schrieb:

    Ueberhaupt gehe ich davon aus, dass irgendwannmal irgendjemand einen Fall gefunden hat, wo break tatsaechlich dazu fuehrte, dass die Schleife nich verifizierbar war. Er wurde dann in einem Paper publiziert und seit dem glaubt man das einfach. 😃

    Daran glaube ich eher nicht. Ich sehe keinen Grund, warum man die Nachbedingung nicht auch so formulieren können sollte, dass sie auch im break-Fall korrekt ist.

    Ob man break nun verwendet oder nicht ist mir eigentlich ebenfalls herzlich egal. 😉 Nur wenn es tatsächlich handfeste Gründe gibt es nicht zu tun, dann würde ich das gerne wissen. Deswegen frage ich hier nach.



  • Vielleicht solle mal jemand eine Schleife posten, die ohne "break" nicht auskommt. Deshalb denke ich mir mal schnell eine aus :

    #include <stdlib.h>
    #include <stdio.h>
    
    int main ()
    {
     randomize ();
    
     int i;
    
     for ( i = 0; i < 100; i++ ) {
    
      if ( (rand () % 100) > 90 ) break;
    
      printf("%d ", i);
    
     }
    
     return 0;
    }
    

    Wie kann man jetzt prüfen, ob die For-Schleife von i = 0 bis i = 99 korrekt arbeitet ?

    P.S.: Auskommentieren gilt nicht ! 🙂



  • merker schrieb:

    Wie kann man jetzt prüfen, ob die For-Schleife von i = 0 bis i = 99 korrekt arbeitet ?

    indem man die werte kennt, die von rand() kommen. das sind ja immer dieselben 😉



  • merker schrieb:

    Vielleicht solle mal jemand eine Schleife posten, die ohne "break" nicht auskommt.

    So eine Schleife gibt es nicht.



  • merker schrieb:

    Vielleicht solle mal jemand eine Schleife posten, die ohne "break" nicht auskommt. Deshalb denke ich mir mal schnell eine aus :

    Ich habe sie mal ein wenig modifiziert.

    #include <stdlib.h>
    #include <stdio.h>
    
    int main ()
    {
     randomize ();
    
     int i;
    
     for ( i = 0; i < 100 && rand() % 100 > 90; i++ ) {
    
      printf("%d ", i);
    
     }
    
     return 0;
    }
    

    Wie finix bereits sagte, solch eine Schleife existiert nicht.



  • Ähem, vielen Dank für die Antworten. 🙂

    Ich wollte mit meiner Schleife nur folgendes klarmachen :

    Schleifen mit mehr als einer Laufbedingung sind nicht validierbar !

    Deshalb erübrigt sich die Frage, ob man eine Schleife mit "break" verlassen darf oder ob man besser den "Schleifenkörper :-)" umformuliert.



  • merker schrieb:

    Schleifen mit mehr als einer Laufbedingung sind nicht validierbar !

    und warum nicht?



  • Weil die Laufbedingungen voneinander unabhängig sind obwohl sie zusammen eine Schleife (Einheit, Kontrollstruktur) bilden.

    Würde man zu "Testzwecken" eine oder mehrere Laufbedingungen auskommentieren, würde man "irgendwas" aber nicht die Schleife testen.



  • EDIT: Hat Apollon schon gemacht.



  • ich hab jetzt die ersten paar seiten gelesen und da hat keiner geschrieben, dass man dieschleife in ne funktion paken und dann return machen kann, darum schreibich es jetzt mal.



  • merker schrieb:

    Weil die Laufbedingungen voneinander unabhängig sind obwohl sie zusammen eine Schleife (Einheit, Kontrollstruktur) bilden.

    aber ist das nicht egal?
    wenn beide bedingungen vorhersehbar sind, kann man doch ganz genau bestimmen, wie sich die schleife verhalten wird.
    es sei denn die eine bedingung ist echt zufällig, aber an 'rand()', wie in dem beispiel, ist ja nun wirklich gar nichts zufällig...
    🙂



  • also schrieb:

    ich hab jetzt die ersten paar seiten gelesen und da hat keiner geschrieben, dass man dieschleife in ne funktion paken und dann return machen kann, darum schreibich es jetzt mal.

    Hättest mal bis zur 4. lesen sollen:

    pale dog schrieb:

    Jester schrieb:

    Simon2 schrieb:

    while(irgendeine Bedingung && !(erste Operation erfolgreich))
       zweite Operation
    

    Wieso nicht ?

    Mach bitte aus erste Operation was zwei- oder dreizeiliges. 🙂

    bool erste_operation_erfolgreich()
    {
      ...
    }
    

    4 zeilen 😉

    :p 😉

    Gruß,

    Simon2.



  • // nach einer swap operation soll abgebrochen werden (sinn sei dahingestellt)
    bool swapped;
    do{
    	swapped = false;
    	for(int i = 1; i < v.size(); ++i){
    		if(v[i] < v[i-1]){
    			swap(v, i, i-1);
    			swapped = true;
    		}
    	}
    } while(swapped);
    
    // hier wird das ganze erledigt, indem die zählervariable auf einen wert gesetzt wird,
    // der im NÄCHSTEN durchlauf zum abbruch führt.
    // zudem ist es vielleicht nicht für jeden sofort ersichtlich.
    bool swapped;
    do{
    	swapped = false;
    	for(int i = 1; i < v.size(); ++i){
    		if(v[i] < v[i-1]){
    			swap(v, i, i-1);
    			swapped = true;
    			i = v.size();
    		}
    	}
    } while(swapped);
    
    // ähnlich wie das vorherige beispiel, allerdings ist das kriterium hier eine eigene variable.
    // dieselbe, die auch für die äußere schleife verwendet wird.
    // vielleicht einfacher zu verstehen, aber man muss nachgucken, warum "swapped" hier schon
    // relevant ist.
    bool swapped;
    do{
    	swapped = false;
    	for(int i = 1; i < v.size() && !swapped; ++i){
    		if(v[i] < v[i-1]){
    			swap(v, i, i-1);
    			swapped = true;
    		}
    	}
    } while(swapped);
    
    // hier macht es ein break
    // wahnsinnig einfach zu verstehen. wenn ein swap stattgefunden hat, wird die schleife abgebrochen
    bool swapped;
    do{
    	swapped = false;
    	for(int i = 1; i < v.size(); ++i){
    		if(v[i] < v[i-1]){
    			swap(v, i, i-1);
    			swapped = true;
    			break;
    		}
    	}
    } while(swapped);
    


  • keinlehrer schrieb:

    // (sinn sei dahingestellt)
    

    Dein Beispielt trifft ein bisschen auf BubbleSort zu, wo man die äußere Schleife sofort abbrechen lassen kann, wenn in der inneren kein Tausch stattgefunden hat, um Performance zu gewinnen ...



  • Simon2 schrieb:

    also schrieb:

    ich hab jetzt die ersten paar seiten gelesen und da hat keiner geschrieben, dass man dieschleife in ne funktion paken und dann return machen kann, darum schreibich es jetzt mal.

    Hättest mal bis zur 4. lesen sollen:

    Seite 4 suche nach return -> 0 treffer.



  • merker schrieb:

    Weil die Laufbedingungen voneinander unabhängig sind obwohl sie zusammen eine Schleife (Einheit, Kontrollstruktur) bilden.

    Würde man zu "Testzwecken" eine oder mehrere Laufbedingungen auskommentieren, würde man "irgendwas" aber nicht die Schleife testen.

    Und, weiter?



  • Eine Schleife -> Eine Laufbedingung.

    Das ist eigentlich alles soweit. 🙂

    pale dog schrieb:

    aber ist das nicht egal?
    wenn beide bedingungen vorhersehbar sind, kann man doch ganz genau bestimmen, wie sich die schleife verhalten wird.

    Das ist gut gesagt ! Man bestimmt, wie sich die Schleife verhalten wird. Sowas ist kein Test.



  • merker schrieb:

    pale dog schrieb:

    aber ist das nicht egal?
    wenn beide bedingungen vorhersehbar sind, kann man doch ganz genau bestimmen, wie sich die schleife verhalten wird.

    Das ist gut gesagt ! Man bestimmt, wie sich die Schleife verhalten wird.

    ja, und? 😕
    das geht doch aucht bei mehreren abbbruchbedingungen?



  • merker schrieb:

    Schleifen mit mehr als einer Laufbedingung sind nicht validierbar !

    Würde mich auch interessieren warum nicht.

    void my_strncpy(char* dest, char const* src, size_t length)
    {
        while (length && *src)
        {
            *dest++ = *src++;
            length--;
        }
        if (length)
            memset(dest, 0, length);
    }
    

    Wo ist da jetzt das Problem?
    Und wenn du jetzt sagst das gilt nicht als "mehr als einer Laufbedingung", dann sage ich: definiere "mehr als einer Laufbedingung" 😃



  • halte die aussage "Schleifen mit mehr als einer Laufbedingung sind nicht validierbar !" für unhaltbar. natürlich sind auch schleifen mit mehr als einer laufbedingung validierbar.

    allerdings vertrete ich trotzdem die auffassung: je weniger laufbedingungen, desto gut 😉

    die verwendung von kontrollstrukturen wie break und continue sorgt, korrekt angewendet, für wesentlich bessere lesbarkeit eines stückes code.

    das beispiel von hustbaer setzt kenntnis der funktionsweise von C voraus, um den code verstehen zu können. man muss wissen, dass C den wert 0 als bool'schen ausdruck akzeptiert. zudem muss man wissen, was der dereferenzierungsopertor * tut.

    natürlich könnte man jetzt argumentieren, dass sich niemand ohne C kenntnis einen C quellcode angucken sollte. aber ich bin der meinung, dass man code so gestalten sollte, dass er die einfachst mögliche verständnis bei fremdlesern ermöglicht. das hat nun natürlich nicht direkt was mit "break" zu tun, ist aber allgemeingültig.


Anmelden zum Antworten