www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik switch case


Autor: Hannes Weninger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Basti (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael Wilhelm (Gast)
Datum:

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

MW

Autor: Johnny (Gast)
Datum:

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

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

Autor: jmoney (Gast)
Datum:

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

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder kürzer & schneller:

if (((unsigned)x) < 27)

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

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

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


Wo ist der Unterschied??

Autor: Basti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wo ist der Unterschied??

das drumrum, sonst nix

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ansonsten einfach mischen...

bereiche in den default zweig der case abfrage...

d.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

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

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Fritz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..naja wenn es sich um einen unsigned typen handelt, nat...

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo, das sieht effektiver aus :-)

Autor: Big_Daddi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

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

Autor: Stefan (Gast)
Datum:

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

Stefan.

Autor: Big_Daddi (Gast)
Datum:

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

oder???

Autor: Philipp Sªsse (philipp)
Datum:

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

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.