# switch-case Konstrukt auch mit case i < 6: s = 6 ?



## PELLE (15. Jun 2007)

Hallo,


```
switch (zensur)
{
          case '1': ausgabe="sehr gut";
                    break;
          case '2': ausgabe="gut";
                    break;
          case '3': ausgabe="befriedigend";
                    break;
          case '4': ausgabe="ausreichend";
                   break;
          case '5': ausgabe="mangelhaft";
                   break;
          case '6': ausgabe="ungenuegend";
                   break;
          default: ausgabe="falsche Eingabe";
                   break;

}
```

erlaubt das switch-case Konstrukt auch vergleiche wie case i < 6: note = 6; ??

Habe nichts darüber gefunden fände es aber sehr geschickt.


----------



## Beni (15. Jun 2007)

Nein, erlaubt es nicht. Beim switch geht es darum, möglichst schnell an einen bestimmten Punkt zu springen, möglichst ohne Vergleiche zu machen.


----------



## SlaterB (15. Jun 2007)

oh interessant,

abgesehen davon, dass das nicht gerade sinnvoll ist
(oder es sollte ein weiteres switch mit der Möglichkeit für Bereiche geben)
wie wird das denn intern gebaut, so dass es ohne Vergleiche geht?


----------



## Beni (15. Jun 2007)

Es gibt zwei Implementierungen:
- tableswitch: Entweder wird ein Array gemacht, in dem Sprungaddressen stehen. Der Wert im switch wird dann als Index verwendet, um die Sprungaddresse zu lesen, und dann wird gesprungen (... zu dem Bytecode, der ausgeführt werden soll).
- lookupswitch: Oder es wird eine Tabelle gemacht, wenn der Array zuviele "Löcher" hätte (weil es so Dinge wie "case 87586:" gibt...).

Wir hatten gestern Besuch von einem Entwickler, der an der JVM mitgeschrieben hat... deshalb weiss ich jetzt solche Dinge :bae:


----------



## SlaterB (15. Jun 2007)

hmm, für beide könnte man mit etwas Compilerarbeit begrenzte Bereiche in Einzelelemente auflösen,

wenn aber ein ahnungsloser User 
i<6 bei Integer
oder selbst beidseitig begrenzt 
0<i<100000
schreibt, dann ist es wirklich besser darauf zu verzichten 

da könnte man man höchstens auf einen noch intelligenteren Compiler hoffen,
der das ganze teilweise als if/else + teilweise als switch baut,
oder gleich komplett als if/else, kommt ja oft nur auf die Kurzschreibweise an, nicht auf die Geschwindigkeit


----------



## PELLE (15. Jun 2007)

ja mit if/else gehts natürlich nur sieht es mit case weit übersichtlicher aus da ich ca. 50 if else vergleiche mache...


----------



## Ark (15. Jun 2007)

Wenn die Größen der Bereiche einen brauchbaren ggT haben, könntest du auch vorher eine Division durchführen. 

Ark


----------



## Hilefoks (15. Jun 2007)

@Beni: erzähl mehr von deinem Wissen - solche Detailfragen sind sehr interessant. Am besten in einem eigenen Thread. ;-)


----------



## Beni (15. Jun 2007)

Lese doch selber: klick :wink: So ab Kapitel 3 könnte es für dich ganz interessant werden. (Falls du nur Bytecode haben willst: hier)
[Edit: bevor hier jemand auf falsche Gedanken kommt. Ich habe das Buch *nicht* gelesen :bae: ]


----------



## Hilefoks (15. Jun 2007)

:###


----------



## hansz (16. Jun 2007)

Hallo zusammen,
für alle die es interessiert habe ich noch etwas zu den JVM-Befehlen tableswitch und lookupswitch:

Übergang von einer tableswitch-Realisierung einer switch-Anweisung zu einer Realisierung mit dem Befehl lookupswitch bei unterschiedlichen case-Konstanten (verwendeter Compiler: javac, Version 1.6.0):

case-Konstanten || Realisierung auf Bytecodeebene
1, 2, 3 || tableswitch
1, 2, 4 || tableswitch
1, 2, 5	|| tableswitch
1, 2, 6 || lookupswitch
1, 2, 7 || lookupswitch
-50, 230, 2 || lookupswitch

Ein Beispiel mit den case-Konstanten 3, 4 und 6:


```
public class Test {  
  public static void main(String[] args)   {
    int a = 4;
    int b = 0;
    switch (a) {
      case 3: b++; 
              break;
      case 4: b += 2; 
              break;
      case 6: b += 3; 
              break;
      default: b += 5;
    }  
    b--;
  }
}
```

Die JVM-Befehle von main sind dann:


```
0: iconst_4
1: istore_1
2: iconst_0
3: istore_2
4: iload_1
5: tableswitch { //3 to 6
    3: 36;
    4: 42;
    5: 54;
    6: 48;
   default: 54 }
36: iinc 2, 1
39: goto 57
42: iinc 2,2
45: goto 57
48: iinc 2,3
51: goto 57
54: iinc 2,5
57: iinc 2,-1
```

Zahlenwerte (Bytecode) für die switch-Anweisung innerhalb der Klassendatei:


```
aa 00 00 00 00 00 31 00 00 00 03 00 00 00 06 00
00 00 1f 00 00 00 25 00 00 00 31 00 00 00 2b
```

Die Bedeutung der Bytes:


```
5: aa              Opcode tableswitch
6: 00 00           2 Padding-Bytes
8: 00 00 00 31     default = 49, (5 + 49 = 54)
12: 00 00 00 03     low = 3
16: 00 00 00 06     high = 6
20: 00 00 00 1f     offset1 = 31, (5 + 31 = 36)
24: 00 00 00 25     offset2 = 37, (5 + 37 = 42)
28: 00 00 00 31     offset3 = 49, (5 + 49 = 54)
32: 00 00 00 2b     offset4 = 43, (5 + 43 = 48)
```


----------

