Forum: Mikrocontroller und Digitale Elektronik switch case


von Hannes Weninger (Gast)


Lesenswert?

 Hallo,

Ich möchte bei einer case- Anweisung von 0-26 abfragen, geht das 
überhaupt mit switch case und wie wenn ja?

      switch(x) {
        case 0...26: break;
        case:        break;
        case:        break;
      }

Vielen Dank für Eure Hilfe;
lg
Hannes

von Basti (Gast)


Lesenswert?

wie wäre es mit

if (x >= 0 && x < 27)

ich meine bei switch case geht das nur bei einem wert, also case 1 case 
'X' oder so

von Michael Wilhelm (Gast)


Lesenswert?

switch(x)
{
  case 0:
  case 1:
  ...
  case 26:  tu_was;
  break;
  case 27:  tu_was_anderes;
  break;
  ...
  default: tu_gar_nix;
  break;
}

MW

von Johnny (Gast)


Lesenswert?

> wie wäre es mit if (x >= 0 && x < 27)

Ja genau, warum kompliziert wenns auch einfach geht...

von jmoney (Gast)


Lesenswert?

Naja wenn man aus der PASCAL-Ecke kommt, kann man den Wunsch schon 
verstehen. Da ist iirc ein
1
case x of 0..26:
 möglich.

von Dirk (Gast)


Lesenswert?

oder kürzer & schneller:

if (((unsigned)x) < 27)

von Philipp S. (philipp)


Lesenswert?

Ich weiß nicht, wie clever die einzelnen Compiler sind, aber Michaels 
Lösung würde wohl meist in eine uneffektive Abfrageorgie übersetzt 
werden. Das ist nix.

Bastis "Lösung" ist hier vermutlich zu unübersichtlich, sonst wäre ja 
nicht nach switch gefragt. Wenn man einen Haufen Einzelwerte hat, aber 
auch ein Grüppchen, macht man das nicht mit einem Berg else if, sondern 
packt den Bereich ins default:

switch(x) {
  case 42: dings(); break;
  case 99: bums(); break;
  case 111: bla(); break;
  default:
    if (x >= 0 && x <= 26)
      foo();
    else
      bar();
    break;
 }

Sollte m.E. flott und dabei zumutbar übersichtlich sein.

von Matthias (Gast)


Lesenswert?

Basti:
if (x >= 0 && x < 27)...

Philipp Sªsse:
if (x >= 0 && x <= 26)...


Wo ist der Unterschied??

von Basti (Gast)


Lesenswert?

>Wo ist der Unterschied??

das drumrum, sonst nix

von dennis (Gast)


Lesenswert?

ansonsten einfach mischen...

bereiche in den default zweig der case abfrage...

d.

von pumpkin (Gast)


Lesenswert?

kein problem, aber eher unschön:

switch (käsekuppe)
{
   case 0:
   case 1:
   case 2:
   case 3:
   case 4:
   case 5:
   case 6:
   [...]
   case 24:
   case 25:
   case 26:
      anweisung();
      break;
   case 27:
      break;
   default:
      break;
}

wenn du die "break's" weglässt, rennt er durch bis zum ersten "break".

pumpkin

von crazy horse (Gast)


Lesenswert?

das dürfte dann aber wirklich in 26 Einzelvergleiche hinauslaufen, 
logisch zwar korrekt, aber laufzeitmässig ziemlich mangelhaft...

von pumpkin (Gast)


Lesenswert?

>> Wo ist der Unterschied??

> das drumrum, sonst nix

mmmh, mal wieder eine gefährliche aussage.

kommt auf deine datentypen an. bei integer ist da kein unterschied, aber 
bei gebrochenen zahlen (float, etc) ist der unterschied gewaltig (und 
selbsterklärend).

pumpkin

von pumpkin (Gast)


Lesenswert?

> das dürfte dann aber wirklich in 26 Einzelvergleiche hinauslaufen,
> logisch zwar korrekt, aber laufzeitmässig ziemlich mangelhaft...

danke für den hinweis.

"kein problem, aber eher unschön:"

pumpkin

von A.K. (Gast)


Lesenswert?

> das dürfte dann aber wirklich in 26 Einzelvergleiche hinauslaufen,
> logisch zwar korrekt, aber laufzeitmässig ziemlich mangelhaft...

Unterschätzt den Compiler nicht. Was switch-statements angeht sind die 
recht leistungsfähig, kennen diverse Varienten der Codegenerierung, 
rechnen ein bischen herum und suchen sich die passende aus. Da sind auch 
welche drunter, die man in Assembler-Programmierung kaum vernünftig 
hinbekommt, wie beispielsweise der recht häufig genutzte tree search 
(hier wohl nicht relevant). Lieber mal ausprobieren und nachsehen.

von Fritz (Gast)


Lesenswert?

Das sehe ich wie A.K. Der Compiler macht es schon effektiv, egal wie 
unsortiert der Input sein mag.
Die Lösung von Michael ist zwar länglich, aber klar und deutlich, ohne 
Gemurkse.

von crazy horse (Gast)


Lesenswert?

da steht "dürfte"...
Was der Compiler draus macht, kann man nicht vorhersehen, zumindest 
nicht allgemeingültig. Da hilft nur nachschauen im listing.
Ich habs gerade mal mit CodeVision gemacht:

while (1)
      {loop++;
      switch (loop)
      {case 0:
       case 1:
       case 2:
       case 3:
       case 4:
       case 5:
       case 6:
       case 7:
       case 8:
       case 9:
       case 10: {test();
                break;
                }
       default: break;
       }
000066 5f0f        SUBI R16,-1
                 ;     110       switch (loop)
000067 2fe0        MOV  R30,R16
                 ;     111       {case 0:
000068 30e0        CPI  R30,0
000069 f011        BREQ _0xA
                 ;     112        case 1:
00006a 30e1        CPI  R30,LOW(0x1)
00006b f409        BRNE _0xB
                 _0xA:
                 ;     113        case 2:
00006c c002        RJMP _0xC
                 _0xB:
00006d 30e2        CPI  R30,LOW(0x2)
00006e f409        BRNE _0xD
                 _0xC:
                 ;     114        case 3:
00006f c002        RJMP _0xE
                 _0xD:
000070 30e3        CPI  R30,LOW(0x3)
000071 f409        BRNE _0xF
                 _0xE:
                 ;     115        case 4:
000072 c002        RJMP _0x10
                 _0xF:
000073 30e4        CPI  R30,LOW(0x4)
000074 f409        BRNE _0x11
                 _0x10:
                 ;     116        case 5:
000075 c002        RJMP _0x12
                 _0x11:
000076 30e5        CPI  R30,LOW(0x5)
000077 f409        BRNE _0x13
.
.
erkennt also die mögliche Vereinfachung nicht.

von dennis (Gast)


Lesenswert?

unser compiler für ppc`s bekommt das ganz gut auf die reihe, selbst für 
komplizierte "mischungen".
um sicher zu gehen, lieber ein if konstrukt verwenden, wenn es bei einem 
oder 2 bereichen und vielen einzelabfragen bleibt, ist das nicht 
unübersichtlich, zudem ist man sicher das kein ellenlanger asm code 
produziert wird, egal welchen compiler man nutzt.

d.

ps.: da ist sie man wieder, die harwareunabhängigkeit von c, die alle in 
den wahnsinn treibt...

von Andreas (Gast)


Lesenswert?

wie wäre es dennn mit dem hier:

if (x >= 0 && x < 27) case 0..27
{
  ...
}
else if( x >= 27 && x < 30 ) case 27..20
{

 ...
}
else if( x >= 30 && x < 35 )case  30..35
{

 ...
}
 usw...

else  default

von dennis (Gast)


Lesenswert?

if (x >= 0 && x < 27) case 0..27
{
  ...
}
else if( x < 30 ) case 27..20
{

 ...
}
else if( x < 35 )case  30..35
{

 ...
}


du meinst wohl so...

nachteil:
verschachtelung, wie bei allen if else Konstrukten...
d.

von dennis (Gast)


Lesenswert?

..naja wenn es sich um einen unsigned typen handelt, nat...

von A.K. (Gast)


Lesenswert?

@crazy horse:

    while (1) {
  loop++;
  switch (loop) {
  case 0:
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
  case 9:
  case 10:
      test();
      break;
  default:
      break;
  }
    }

wird bei GCC (-Os) zu

.L20:
  adiw r28,1
  cpi r28,11
  cpc r29,__zero_reg__
  brsh .L20
  rcall test
  rjmp .L20

von crazy horse (Gast)


Lesenswert?

jo, das sieht effektiver aus :-)

von Big_Daddi (Gast)


Lesenswert?

Hi,

kann man im Assembler einfach so wie in C die Switch Case Funktion 
einbauen?? oder muss das anders programmiert werden??

von Stefan (Gast)


Lesenswert?

es gibt in Assembler nicht direkt sowas wie switch case, mann muss es 
also zu Fuß implementieren. Sollte aber machbar sein.

Stefan.

von Big_Daddi (Gast)


Lesenswert?

dann vielleicht eher mit der vergleichsfkt. realisieren oder?? Also mit
cmp Var, 4
Befehl ausführen
cmp Var, 3
Befehl ausführen

oder???

von Philipp S. (philipp)


Lesenswert?

Oder, wenn viele der case-Fälle direkt nebeneinander liegen, mit einer 
Sprungtabelle, also über den Wert indirekt die Sprungtabelle laden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.