Wieso Switch-Case nur mit ganzen Zahlen?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Hallo,

als Anfänger habe ich mir diese Frage auch oft gestellt. Heute würde ich sagen, wenn ich mir diese Frage wieder stellen würde, dass ich etwas falsch mache, wenn ich das so benötige. Welchen guten Grund gibt es dafür? Auch mit Zahlen lassen sich abfragen sehr komplex gestalten. Hinzu kommt, dass Switches in der Regel besondere Strukturen sehr gut abbilden und nicht zwingend als Ersatz für viele If-Abfragen gesehen werden sollte, denn auch dann hast du etwas falsch gemacht. Der Vorteil bei Switches ist, dass du durch die Cases durchfallen kannst und so ggf. optionalen Code ausführen kannst.

Mir ist klar, dass ich dir nicht unbedingt eine Antwort auf deine Frage gegeben habe, aber denk darüber nach, ob dein Code so sinnvoll ist. Viele If-Abfragen oder Switch-Statements deuten in der Regel auf eine Design-Problem hin. Wie schon gesagt, wofür benötigst du Strings in Switch-Statements? Du kannst gerne einen Kommentar da lassen und ggf. kann ich dir dann eine Alternative nennen dein Problem zu lösen.


Rayzn 
Fragesteller
 01.12.2013, 00:33

Hi,

danke erst mal für die Antwort.

Ich will z.B. gerade eine Konsolenanwendung programmieren, bei dem man verschiedene Befehle eingeben kann, durch die dann unterschiedliche Funktionen oder Programme ausgeführt werden. Das ist jetzt bei mir eine if-else-kette in einer endlosschleife mit cin.getline am Anfang.

Ich freue mich immer über Verbesserungsvorschläge, da ich besonders von Programm-Design, "schönen" und optimalen Code keine Ahnung habe. Ich kann mir ehrlich gesagt schwer vorstellen, wie man das Problem anders lösen kann, aber ich bin ja auch noch nicht besonders weit.

mfg

0
Sasatux  01.12.2013, 01:01
@Rayzn

Hallo, das ist ja schon ein Standard-Problem.

Die Frage ist natürlich nur, ob du Parameter übergeben willst um das Verhalten zu steuern, oder ob dein Programm ein Command Line Interface(CLI) ist. Also ähnlich wie MySQL etc. Bei denen kann man aber auch zwischen Live-Konsole und Parameter unterscheiden. Ein sehr mächtiges Beispiel für so ein interface ist unter Linux die "find"-Anwendung. Die Parameter können sehr komplex sein.

In diesem Falle ist diese Ansatz tatsächlich nicht falsch. Der Trick bei der Sache ist, dass du einfach ein Struct mit den Bezeichnungen auf Zahlen-Werte legst oder einzelne Buchstaben benutzt, welche natürlich als Char(Byte -> Zahl) gespeichert werden. Es gibt dafür sehr gute Klassen, welche sehr oft genutzt werden. Unter Linux ist wohl GNU Getopt ein Standard. So weit ich weiß ist das auch unter Windows gut lauffähig. Unix natürlich auch. Und sonst würde mir noch Boost einfallen, dort gibt es ja allgemein sehr viele gute Klassen.

http://www.boost.org/doc/libs/1_55_0/doc/html/program_options.html

http://www.gnu.org/software/libc/manual/html_node/Getopt.html#Getopt

Ich hoffe das hilft dir weiter. Sonst frag einfach noch einmal nach.

Es gibt natürlich noch unzählige weitere Möglichkeiten ;-) So wie immer.

0
Rayzn 
Fragesteller
 01.12.2013, 15:38
@Sasatux

Ok danke, dann werde ich mich mir mal GNU Getopt und Design-Patterns anschauen. Boost behalte ich mir im Hinterkopf.

0
Rayzn 
Fragesteller
 03.12.2013, 03:22
@Sasatux

Hey, ich habe gerade Probleme mit der Installation von Boost. Ich benutze Code::Blocks(Mingw) mit Windows7 (64) und bekomme bei den Lösungswegen, die ich bis jetzt gefunden habe Fehlermeldungen. Es hat zwar wenig mit der ursprünglichen Frage zu tun, aber weißt du, was ich in den Umgebungsvariablen eintragen soll und welche .bat ich dann im boost ordner ausführen soll?

0
Sasatux  06.12.2013, 10:31
@Rayzn

Hi,

entschuldige die späte Rückmeldung. Ich habe auf dem Handy eine Antwort angefangen und dann ist beim Senden das WLAN verreckt. Leider ist dann die Antwort futsch gewesen. Danach habe ich es vergessen ;-)

Leider kann ich dir da nicht weiter helfen. Ich habe im Moment keine Virtuelle Maschine mit Windows installiert und ich nutze Windows leider schon so ewig nicht mehr, dass ich bei so speziellen Problemen nicht unbedingt eine Antwort weiß.

http://stackoverflow.com/a/17879274

Das ist alles, was ich nun finden konnte. Eventuell möchtest du auch QT-Creator testen? Ist meiner Meinung nach im Moment die "kompletteste IDE". Abgesehen von Visual-Studio, aber die ist leider auf MSVC++ fokussiert.

Ich hoffe das hilft ein bisschen, denn sonst weiß ich leider auch nicht weiter. Unter Linux habe ich solche Probleme zum Glück überhaupt nicht... Faulheit siegt halt immer. Bei mir macht das alles mein Paket-Manager und ich gebe einfach nur ein, welches Programm ich haben will, der Rest passiert dann ohne mein Zutun...

Ach. Und welchen Compiler+Linker nutzt du? Denn wenn du "Makefiles" oder "pro"-Dateien hast, dann kann es sein, dass du dem Linker sagen musst, welche Dateien dem Projekt hinzugefügt werden müssen... Aber das ist sehr speziell ;-)

0

Ganz einfach: Weil Strings komplexe Datentypen sind - Objekte, wenn du so willst.

Um die zu vergleichen muss bekanntlich eine Komparatorfunktion verwendet werden (auch in jedem if-Statement!), weil ein einfacher Vergleich der Adressen selten das ist, was man will.

Der Compiler behandelt ein switch-Statement auch nur als primitiven Vergleich (eben mehrere Vergleiche) und ruft da nicht irgendwelche Komparatoren auf.

In Java kann man neuerdings auch Strings in switch-Statements verwenden. Das hilft dir jetzt aber wenig...


koch234  29.11.2013, 10:15

ich staune immer wieder ;-)

0

String ist in C++ kein Basisdatentyp und in Switch-Case-Anweisungen muss eine Ganzzahl verwendet werden, weil daraus später (nach dem Compilieren) eine Sprungtabelle wird. Um Fallunterscheidungen mit Strings zu machen, musst du if-else-Strukturen nehmen.


dergutekoenig  29.11.2013, 09:42

Wobei es ja durchaus anders geht. In Java ist das beispielsweise seit (ich glaube) Version 6 möglich.

Die Designer von C++ haben sich aber dagegen entschieden - ich vermute, aus Effizienzgründen, weil ein String-Handling bei Switch-Case intern ja irgendwie auf eine prozessorverträgliche Art und Weise "umgebaut" werden muss. Ich vermute, dass dabei einiges an Overhead entsteht, der vermutlich nicht zum Effizienz-Konzept von C++ passt.

3
martin7812  29.11.2013, 09:59

Durchaus möglich wäre es auch noch mit floating-point-Zahlen (wird aber ebenfalls z.Z. von keinem Compiler unterstützt).

Der Compiler könnte dann z.B. eine float32-Zahl als uint32-Zahl "sehen"; aus:

case(float_zahl)

würde dann intern:

case(*(uint32 *)&float_zahl)

Effizient ist das Ganze natürlich nicht.

0