hallo, ich möchte in meine code eine switch-case auf eine variable
ausführen - der compiler schluckt das aber nicht, er besteht auf eine
Konstante.
wenn ich schreiben
1
switch(anzahl){
2
case1:
3
case2:
4
...
5
}
funktioniert es, ersetze ich aber "1", "2",... durch "variable_1",
"variable_2",... geht es nicht mehr!
warum benötigt der compiler hier unbedingt konstanten und kann nicht mit
variablen arbeiten?
Zweite (und wichtigere) Frage:
wenn ich keine if-else-Anweisung benützen will, wie löse ich das Problem
mit den variablen? ich hab mal gehört dass if-else-Anweisung deutlich
länger benötigen als die switch-case, deswegen wäre mir ein switch
lieber!
Danke!
uwe schrieb:
> warum benötigt der compiler hier unbedingt konstanten und kann nicht mit> variablen arbeiten?
Weil das so in der Vorgabe C-Standard steht. Wäre andernfalls mehrdeutig
(könnte mehrfach mit gleichem Wert auftreten).
> wenn ich keine if-else-Anweisung benützen will, wie löse ich das Problem> mit den variablen?
Garnicht, oder Tabelle mit Zeigern auf Funktionen.
GCC Spezialiät: computed goto, aka Tabelle von Labels. Siehe Manual.
>Garnicht, oder Tabelle mit Zeigern auf Funktionen
okay, kannst Du mir dann bitte verraten wie ich das mit den Zeigern
mache?
sry wenn ich so blöd frage, mit zeigern und pointern habe ich zwar
bereits gearbeitet, aber prinzipiell bringe ich mir das programmieren
selbst bei, hab also keinen "großen, weisen Mentor"
Danke!!
PS: Was oben noch fehlte, um die Variablen ins Spiel zu bringen: Vor dem
Aufruf für den passenden Inhalt sorgen:
tabelle[variable_1]= f66;
tabelle[variable_2]= f77;
Ob das so wirklich sinnvoller als if/else ist wäre im Einzelfall zu
klären. Wahrscheinlich nicht, oder nur wenn fast alle Fälle Konstanten
sind.
uwe schrieb:
> hallo, ich möchte in meine code eine switch-case auf eine variable> ausführen - der compiler schluckt das aber nicht, er besteht auf eine> Konstante.
Tip: C-Buch kaufen und lesen.
> ich hab mal gehört dass if-else-Anweisung deutlich> länger benötigen als die switch-case, deswegen wäre mir ein switch> lieber!
Nach Hoerensagen optimieren kann nur in's Auge gehen.
Tip2: Fang mit dem Optimieren an, wenn du den Rest kannst - und nimm
solange einfach if.
Dann hast du denn Sinn von switch-case nicht verstanden!
1
unsignedchari=0;
2
3
if(i==0)
4
{
5
// Rufe Funktion 1 auf
6
}
7
else
8
if(i==1)
9
{
10
// Rufe Funktion 2 auf
11
}
12
else
13
{
14
// Rufe Default Funktion auf
15
}
das ganze analog als switch-case sieht so aus:
1
switch(i)
2
{
3
case0:// Rufe Funktion 1 auf
4
break;
5
case1:// Rufe Funktion 2 auf
6
break;
7
default:
8
// Rufe Deault Funktion auf
9
break;
10
}
Überleg dir mal wie dein Compiler etwas derartiges wie du es vorhat
vernünftig (effektiv) in Assembler umsetzen sollst.
Du willst ja so etwas wie:
1
unsignedchari=0;
2
unsignedcharj=1;
3
unsignedchark=2;
4
5
if(i==j)
6
{
7
8
}
9
if(i==k)
10
{
11
12
}
Bissl pervers, oder? Oder was passiert, wenn j == k ? Wie schon oben
geschrieben hast du dann Mehrdeutigkeiten und keine gescheite Logik
mehr.
Bei meinem Compiler ist es wirklich so, dass ein switch-case effektiver
(weniger Code) ist, als ein verschachteltes if-else.
Mein Compiler macht das mit Sprungtabellen (ähnlich wie das Beispiel
oben)
Wobei das für einen Anfänger, der den Sinn von switch-case noch nicht
begriffen hat, total over-sized ist.
Ein Beispiel für den Einsatz von switch-case sind State-Machines.
Oder ganz einfach wenn EINE Variable mehr als 2 Zustände einnehmen kann,
dann bietet sich ein switch-case an.
Aber Variablen mit Variablen vergleichen zu wollen ist mit switch-case,
wie schon erwähnt nicht möglich!
Übrigens ist die Berechnung eines Index in einem Array auch nicht
"umsonst" ;-)
Und wo bitte hast du damit dein Problem gelöst, dass du Variablen
effektiv mit Variablen vergleichen willst?
Und wenn ist das nicht mit einem 1-dimensionalen Array zu machen,
sondern man braucht ein 2-dimensionales!
1
typedefvoid(*fcnptr_t)(void);
2
3
#define MAX_Y 3
4
#define MAX_X 3
5
6
fcnptr_ttabelle[MAX_Y][MAX_X]={{f00,f01,f02},
7
{f10,f11,f12},
8
{f20,f21,f22}
9
};// lauter Funktionen
10
11
unddannaufrufenmit
12
tabelle[i][j]();
Damit kannst du dann wirklich eine Funktion in Abhängigkeit von 2
Variablen aufrufen. Bei 3 usw. Variablen wird das ganz umso komplexer.
Aber allein durch die Berechnung des Indizes hast du so viel Overhead,
dass eine anderes Strategie sicher effektiver wäre.
cheers
> ich hab mal gehört dass if-else-Anweisung deutlich> länger benötigen als die switch-case, deswegen wäre mir ein switch> lieber!
Die 'deutliche Effektivität' (wobei das Wörtchen deutlich noch zu
hinterfragen wäre) rührt gerade aus dem Umstand heraus, dass in den case
Teilen nur Konstante stehen dürfen! Das ermöglicht effizientere
Bearbeitungstechniken. Fällt die Voraussetzung 'da sind nur Konstanten
vorhanden' weg, fällt auch die Voraussetzung für die Sprungstrategie weg
und die effizientere Abarbeitug ist ganz einfach nicht mehr möglich. Da
dann alledings switch-case in Schwierigkeiten kommen kann (weil mehrere
case-Zweige auf den selben Wert ausgewertet werden könnten) wird in
diesem Fall switch-case nicht mehr zugelassen. Vor allen Dingen auch
deshalb, weil es dann mit einer if-else-if Kette ein perfektes Werkzeug
gibt, diese Fälle zu handhaben.
Du versuchst hier eine Logik umzudrehen, wobei diese Umkehrung nicht
zulässig ist.
Und im übrigen gilt: Wenn dein Programm mit einer if/else-if Kette zu
langsam ist, dann ist es das mit einem switch-case ebenfalls. Das sind
Mikrooptimierungen, die zwar eventuell ein paar Prozentpunkte bringen,
die dir aber ein zulangsames Programm nicht um ein paar Größenordnungen
boosten können. Bei Optimierungen setzt man auf der algorithmischen
Ebene an, beim Verfahren, und nicht indem man dort ein paar Nanosekunden
holt und da ein paar Nanosekunden.