switch anweisung / break; notwendig?

Gast #486732
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?
1
  switch(current_pause_type)
2
  {
3
    case 1:{break;};
4
    case 2:{break;};
5
    //case 3:{break;};
6
  }
#486742
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.
#486749
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
Gast #486758
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.
#486761
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
Moderator Persönliche Seite #486773
Lesenswert?

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

Hier die Referenz dazu:

http://www.lysator.liu.se/c/duffs-device.html
#486778
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
1
 do {                          /* count > 0 assumed */
2
   *to++ = *from++;              /* Note that the to pointer is NOT incremented */
3
 } while (--count > 0);

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

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.
Gast #486786
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
Moderator Persönliche Seite #486796
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.
Gast #486798
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren