www.mikrocontroller.net

Forum: Compiler & IDEs switch anweisung / break; notwendig?


Autor: Maggus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

sorry wegen der peinlichen Nachfrage, aber ich bin mir unsicher. Ist 
wohl schon zu spät am Abend. Bei genanntem Code möchte ich innerhalb der 
cases die Variable current_pause_type verändern. Wenn ich innerhalb von 
Case 1 den current_pause_type auf 2 setze, wird dann Case 2 noch 
ausgeführt? Bzw die eigentliche Frage: Ist das break; zwingend 
notwendig?
  switch(current_pause_type)
  {
    case 1:{break;};
    case 2:{break;};
    //case 3:{break;};
  }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, der break ist notwendig.
Ohne würdest du einen sog. 'fall through' machen:


switch( i ) {
  case 1:
    j = 5;

  case 2:
    k = 3;
    break;
}

hat i den Wert 1, dann wird sowohl die Zuweisung zu j
als auch die Zuweisung zu k ausgeführt. Die Programmausführung
fällt also gewissermassen vom case 1 zum case 2 durch, weil da
kein break ist, der dafür sorgen würde, dass das switch-case
insgesamt als beendet erklärt wird.

Autor: Jan Dressler (keyman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo.
also du kannst da verändern was du willst,
alle nachfolgenden befehle werden ausgeführt.
also ein break beendet logischweise das switch. lässt du das break aber 
weg, dann wird er immer den case2 auchnoch ausführen...

beispielcode (ungetestet!):
--------------------------schnipp--------------------------
 int i;
 printf("bitte zahl eingeben: ");
 scanf("%i", &i);
 switch(i) {
   case 1: i--;
   case 2: i++;
   case 3: i=5; break;
   default: i=7;
   }
 printf("i = %i\n", i);
--------------------------schnapp--------------------------

es wird, egal was du eingibst (1, 2 oder 3) immer 5 ausgeben, wenn du 
nicht 1,2 oder 3 eingibst kommt 7 raus.
alles klar?

hoffe das war einleuchtend :)

jan

Autor: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Erklärung ist richtig, aber der ursprüngliche Fragesteller hat 
nicht nur nach dem break gefragt -- er will wohl ausserden noch 
irgendwie die Variable ( bei Dir i, bei ihm  current_pause_type) 
mittendrin verändern.

Unklare Frage -- da kann man eigentlich nicht sinnvoll antworten.

Autor: Jan Dressler (keyman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi.
@stefan salewski: daraum hab ich mich implizit bezogen. hab ja mit 
meinem "i--;" die switch-variable bei der eingabe 1 auf 0 gestzt und 
somit wäre das dann das was er vielleicht auch ausdrücken wollte.
ist mir aber auch erst gekommen als ich den code da hingehauen habe und 
habs dann einfach so gelassen grins

@Karl heinz Buchegger: du warst schneller, das gebe ich zu :) darf ich 
zu meiner verteidigung sagen dass ich nebenher telefoniere (neudeutsch 
skype) ;-)

schönen abend
jan

Autor: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry -- ich hatte mich auf Karl heinz Buchegger bezogen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, es ist wohl wieder mal an der Zeit, Duff's Device auszugraben. ;-)
send(to, from, count)
register short *to, *from;
register count;
{
  register n=(count+7)/8;
  switch(count%8){
  case 0:  do{  *to = *from++;
  case 7:    *to = *from++;
  case 6:    *to = *from++;
  case 5:    *to = *from++;
  case 4:    *to = *from++;
  case 3:    *to = *from++;
  case 2:    *to = *from++;
  case 1:    *to = *from++;
    }while(--n>0);
  }
}

Hier die Referenz dazu:

http://www.lysator.liu.se/c/duffs-device.html

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast recht.
Ich hab ja die Hälfte der Fragestellung überlesen bzw.
die feinen Nuancen der Fragestellung nicht kapiert.

Ist aber logisch: Ein switch-case wertet die Bedingung nur
einmal aus, beim switch. Danach wird der dafür zuständige
case aufgesucht und von dort geht die Programmausführung
weiter bis entweder ein break angetroffen wird oder
das switch-case zu Ende ist.

Mehr steckt da nicht dahinter. Eine interessante Ausnutzung
dieser wenig-strukturierten Eigenschaft eines switch-case
ist "Duffs Device"

dabei geht es um Loop-Unrolling.
Aus
 do {                          /* count > 0 assumed */
   *to++ = *from++;              /* Note that the to pointer is NOT incremented */
 } while (--count > 0);

wird
 switch (count % 8)  /* count > 0 assumed */
 {
   case 0:        do {  *to++ = *from++;
   case 7:              *to++ = *from++;
   case 6:              *to++ = *from++;
   case 5:              *to++ = *from++;
   case 4:              *to++ = *from++;
   case 3:              *to++ = *from++;
   case 2:              *to++ = *from++;
   case 1:              *to++ = *from++;
                     } while ((count -= 8) > 0);
 }

Die Idee ist einfach: Anstatt in einer Schleife immer nur
ein Datenelement umzukopieren, sollen bei einem Schleifen-
durchlauf gleich mehrere Datenelemente umkopiert werden.
Das verringert den Prozentanteil der Schleifensteuerung
in der kompletten Kopierschleife.
Nur hat man ein Problem, wenn die Anzahl der umzukopierenden
Elemente nicht ganzzahlig durch die Anzahl der Kopieraktionen
in der Schleife teilbar ist. "Duffs Device" fungiert hier als
eine Art Schrägeinstieg in die Schleife und sorgt dafür
das beim ersten Schleifendurchlauf entsprechend weniger
Kopieraktionen gemacht werden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diesmal war Jörg schneller :-)
Aber schon interessant, wie sich manchmal Gedankengänge
gleichen.

Autor: Maggus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für eure ausfürliche Hilfestellung.

Im Hinblick auf die Tatsache, dass das switch so im wörtlichen Sinne von 
"switch" gar kein switch ist, bedeutet das also, dass die switch 
anweisung wirklich nur exakt das gleiche bedeutet wie 
hintereinandergereihte ifs. Irgendwie hat die switch-anweisung so 
wesentlich weniger Sinn als ich zunächst annahm. BTW: Ich komme von 
Pascal her und da wird nur und ausschließlich der erste passende case 
abgearbeitet und keine weiteren.

Danke für eure Hilfe. Mir ist jetzt einiges Klarer bei den Fehlern die 
mein Code bis gerade noch produziert hatte.

Markus

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, sie ist eben nicht exakt ein geschachteltes if/else if, sondern
das wird sie nur, wenn man fein sauber das break in jedem Zweig
schreibt.  Je nach Compiler wird sie dann auch in dieser Form
implementiert (wie wohl auch bei Pascal), oder ggf. auch als
Sprungtabelle.

Die Varianten mit fehlendem break sind dagegen in Pascal so nicht
machbar.  Sie sind am ehesten vergleichbar mit etwas schrägen
Programmiertechniken, die man bei reiner Assemblerprogrammierung
machen könnte.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>BTW: Ich komme von Pascal her und da wird nur und ausschließlich der erste 
>passende case abgearbeitet und keine weiteren.

Bei C wird alles bis zum ersten Break ausgefuehrt.

>Irgendwie hat die switch-anweisung so wesentlich weniger Sinn als ich >zunächst 
annahm.

Eine Switch Anweisung wird desoefteren besser vom Compiler in eine 
Sprungtabelle konvertiert als eine If - elsif Anweisung.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.