Irgendwie sitz ich mal wieder auf dem Schlauch. Ich will mittels Case-Anweisung in Abhängigkeit meiner Eingangssignale verschiedene Funktionen ausführen. Jedoch sobald ich einen Zeichen mehrmals verwende, hier 'D' 'P' und 'L' 'P', kommt es zu einer Fehlermeldung. Wie kann ich das umgehen? Habt ihr irgend eine Idee? switch (p[0] & p[1]) { case 'D' & 'P': ... break; case 'G' & 'C': ... break; case 'L' & 'P': ... break; }
Die gewünschte Fehlermeldung: 354: case 'L' & 'P': E 102: duplicate case or default label
Steht doch alles in der Fehlermeldung. Die Case-Anweisung kann nur ein Zeichen überprüfen. Geht nur so:
1 | if(!strncmp(p, "DP", 2)) |
2 | {
|
3 | ...
|
4 | }
|
5 | else if(!strncmp(p, "GC", 2)) |
6 | {
|
7 | ...
|
8 | }
|
9 | else if(!strncmp(p, "LP", 2)) |
10 | {
|
11 | ...
|
12 | }
|
mach mal Klammern um die & in den CASE Zweigen. nicht dass case die beiden Werte einzeln auswertet. Tom
Du solltest dir mal überlegen, was du da eigentlich genau machst! & ist der bitweise Und-Operator.
1 | > p[0] & p[1] |
Das hier heißt mit nichten "lieber Compiler, nimm doch mal bitte das Zeichen p[0] und das Zeichen p[1] und mach das nachfolgende einfach für beide". Sondern die beiden Zeichen werden bitweise verknüpft zu einem neuen. In dem neuen sind alle Bits gesetzt, wo jeweils in beiden Ausgangszeichen auch die Bits gesetzt waren. Das selbe gilt für die case-Labels. Zum Glück meckert der Compiler da rechtzeitig.
Wenn es unbeding eine switch Anweisung sein soll: switch (p[0] | (p[1]<<8)) { case 'D' | ('P'<<8): ... break; case 'G' | ('C'<<8): ... break; case 'L' | ('P'<<8): ... break; }
NoOne schrieb: > Wenn es unbeding eine switch Anweisung sein soll: > ... Hör doch auf, Anfängern so ein Unsinn zu zeigen! Was soll der Blödsinn?
Klaus schrieb: > Du solltest dir mal überlegen, was du da eigentlich genau machst! > > & ist der bitweise Und-Operator. Nö.. in VHDL ist das & der Verkettungsoperator für Vektorliterale. Wo steht das er C oder was syntaktisch kompatibles nutzt? ;P Und in PHP funktionirt ein switch/case auch auf Zeichenketten oder auf boolean werten:
1 | switch(true) { |
2 | case a == b: |
3 | |
4 | case a == 7: |
5 | |
6 | .
|
7 | .
|
8 | }
|
Klaus schrieb: > Hör doch auf, Anfängern so ein Unsinn zu zeigen! Was soll der Blödsinn? Das ist überhaupt kein Unsinn, habe ich selber auch so gemacht. Ein 16Bit Vergleich ist deutlich schneller und codesparender als strncmp. Peter
Peter Dannegger schrieb: > Klaus schrieb: >> Hör doch auf, Anfängern so ein Unsinn zu zeigen! Was soll der Blödsinn? > > Das ist überhaupt kein Unsinn, habe ich selber auch so gemacht. > > Ein 16Bit Vergleich ist deutlich schneller und codesparender als > strncmp. > > > Peter Kann da noch jemand etwas zu sagen? Ich sehe keinen Fehler und Seiteneffekte dürften auch keine auftreten. Zwei Bytes vergleichen muss ich eh und genau das ist hier der Fall, also auch optimale Laufzeit.
avion23 schrieb: > Peter Dannegger schrieb: >> Klaus schrieb: >>> Hör doch auf, Anfängern so ein Unsinn zu zeigen! Was soll der Blödsinn? >> >> Das ist überhaupt kein Unsinn, habe ich selber auch so gemacht. >> >> Ein 16Bit Vergleich ist deutlich schneller und codesparender als >> strncmp. >> >> >> Peter > > Kann da noch jemand etwas zu sagen? Ja. Solange du C-Anfänger bist solltest du in erster Linie danach trachten sauberen C-Code zu schreiben und erst in zweiter Linie auf die effizienteste Lösung schielen. Und besorg dir ein C-Buch Edit: Seh gerade, du bist nicht der ursprüngliche Fragesteller. Die Antwort war für diesen gedacht.
Danke für die rege Beteiligung, dank eurer Hilfe läuft jetzt alles wie es soll. Jetzt zu einer 2. Frage. Ich schicke mittels RS232 Geschwindigkeits- und Zeitdaten zu meinem Controller (z.B V6000T500) und möchte diese speichern. Diese kann ich jetzt in die dafür festgelegten Variablen speichern, bis hier ist alles kein Problem. Jedoch wie realisiere ich es, wenn ich jetzt meinen oben genannten Befehl (VxxxxTxxx) mehrfach hinter ein ander schicke und speichern will?
Jens Sch schrieb: > Jedoch wie realisiere ich es, wenn ich jetzt meinen oben genannten > Befehl (VxxxxTxxx) mehrfach hinter ein ander schicke und speichern will? besorg dir ein C-Buch und arbeite es durch. Das Array, genauso wie eine Struktur sind schon lange erfunden und werden im ersten Drittel deines zu erwerbenden C-Buches besprochen. Die restlichen 2/3 deines noch zu kaufenden C-Buches verwenden diese C-Sprachmittel dann extensiv um darauf aufbauend weitere C-Sprachmittel dem Leser bekannt zu machen bzw. Konzepte zu vermitteln. Von den hunderten kleinen Fallen, die es in C gibt, reden wir erst mal gar nicht. Auch die kommen in deiner Literatur vor und werden erwähnt bzw. Lösungsmöglichkeitne angeboten, was man tun kann, damit es nicht zu Problemen kommt. So ein C-Buch hat nur Vorteile. Nur haben und durcharbeiten müsste man halt eines.
D.h. in dem vom Comiler angemäkelten Case Fall kommt beim Bitweise & zufällig das gleiche raus. Hatte im ersten Moment den Denkfehler, dass da ja jedesmal was anderes rauskommen müsste, aber das ist ja nicht der Fall. Gruß Tom
@Karl Heinz Das wäre vielleicht besser. Habe gerade im Netz "C in 21 Tagen" gefunden. Das werde ich mir wohl mal zu gemüte führen.
Karl heinz Buchegger schrieb: > Solange du C-Anfänger bist solltest du in erster Linie danach trachten > sauberen C-Code zu schreiben und erst in zweiter Linie auf die > effizienteste Lösung schielen. Was ist an einem Switch denn "nicht sauber"? Ich finde so ein Switch auch deutlich besser lesbar, als umständliche if-else-Monster. Und als Anfänger sollte man erst recht lernen, wie man 2 Bytes in 16Bit wandelt und zurück. Denn solche Grundlagen braucht man alle Nase lang. Peter
Danke für eure Hilfe! Jetzt zu einer neuen Frage: Ich verwende die oben beschrieben case-Anweisung und möchte bei einem bestimmten Befehl in einer while-Schleife verbleiben, bis ein weiterer Befehl mich da wieder raus holt. Jedoch funktioniert es nicht so wie es soll. D.h. ich komme rein aber nicht mehr hinaus! switch (p[0] | (p[1]<<8)) { case 'D' | ('P'<<8): ... break; case 'G' | ('C'<<8): ... break; case 'L' | ('P'<<8): x=2; while(x!=1) { if(p[0]=='1'){...} else if(p[0]=='2'){...} else if(p[0]=='3'){...} else if(p[0]=='4'){...x=1;} } break; }
Jens Sch schrieb: > x=2; > while(x!=1) > { > if(p[0]=='1'){...} > else if(p[0]=='2'){...} > else if(p[0]=='3'){...} > else if(p[0]=='4'){...x=1;} > } und wie kriegt p[0] innerhalb dieser while Schleife einen neuen Wert? Ich werde das Gefühl nicht los, das der komplette Ansatz (inklusive dem case) schon verkorkst ist.
Prinzipiell wollte ich den mittels Hyperterminal etc. schicken. Aber das funktioniert ja nicht;)!
Jens Sch schrieb: > Prinzipiell wollte ich den mittels Hyperterminal etc. schicken. Aber das > funktioniert ja nicht;)! Nein. Wo in > x=2; > while(x!=1) > { > if(p[0]=='1'){...} > else if(p[0]=='2'){...} > else if(p[0]=='3'){...} > else if(p[0]=='4'){...x=1;} > } ist eine Anweisung, so dass man sagen kann: Hier kriegt p[0] einen neuen Wert, hier ist die Stelle an der etwas passiert, so dass als Folge davon die Schleife verlassen wird, indem x auf 1 gesetzt wird. Variablen ändern nicht magisch ihren Wert, nur weil du im Hyperterminal auf eine Taste drückst. Jetzt bin ich mir ganz sicher. Der ganze Ansatz (inklusive case) ist verkorkst.
Neue Idee! Ich verwende meine Case-Anweisung wie bisher, da diese ja auch funktioniert und sich mittels Hterm ansprechen lässt. Nur lass ich diesmal die While-Schleife weg und realisiere alles am Funktionsende mit if-Schleifen. if(x1==1){ switch (p[0] | (p[1]<<8)) { case 'D' | ('P'<<8): ... break; case 'G' | ('C'<<8): ... x2=1; x1=0; break; case 'L' | ('P'<<8): ... x3=1; x1=0; break; } } if(x2==1){...} else if(x2==1){...} else if(x3==1){...}
Nunja.. falls p[] neb globales array ist und der Inhalt in der rs232 ISR geändert wird sehe ich eigentlich kein Problem dabei. Allerdings ist vielleicht ne Zustandsmaschine besser geeignet für sowas?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.