Forum: Mikrocontroller und Digitale Elektronik Case-Anweisung mit Zeichen


von Jens S. (jenser)


Lesenswert?

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;
}

von Thomas B. (escamoteur)


Lesenswert?

Hallo,

kannst Du mal die Fehlermeldung geben?

Gruß
Tom

von Jens S. (jenser)


Lesenswert?

Die gewünschte Fehlermeldung:

354:     case 'L' & 'P':
E 102: duplicate case or default label

von Mario (Gast)


Lesenswert?

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
}

von Thomas B. (escamoteur)


Lesenswert?

mach mal Klammern um die & in den CASE Zweigen. nicht dass case die 
beiden Werte einzeln auswertet.

Tom

von Klaus (Gast)


Lesenswert?

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.

von NoOne (Gast)


Lesenswert?

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;
}

von Klaus (Gast)


Lesenswert?

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?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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
}

von Peter D. (peda)


Lesenswert?

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

von avion23 (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens S. (jenser)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Thomas B. (escamoteur)


Lesenswert?

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

von Jens S. (jenser)


Lesenswert?

@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.

von Peter D. (peda)


Lesenswert?

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

von Jens S. (jenser)


Lesenswert?

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;
}

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens S. (jenser)


Lesenswert?

Prinzipiell wollte ich den mittels Hyperterminal etc. schicken. Aber das 
funktioniert ja nicht;)!

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens S. (jenser)


Lesenswert?

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){...}

von Sven (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.