Forum: Compiler & IDEs Verzweigung bei Wert kleiner 0


von Paul P. (dorpreuss)


Lesenswert?

Hallo,

ich habe eine kleine Funktion geschrieben, die einen Wert innerhalb 
angegebener Grenzen inkrementieren bzw. dekrementieren soll.
(wenn Wert > max -> Wert = max-1; wenn Wert < 0 -> Wert = 0)
Sehen wir jetzt mal über die Art der Programmierung hinweg!

Mit dem auskommentierten Teil funktioniert die Funktion. Mit dem 
unkommentierten nicht. Die Abfrage auf kleiner 0 ist hier das Problem. 
Die optimiert der Compiler einfach weg.

Eigenlich wollte ich den Umweg über die temp Variable nicht machen und 
einen cast benutzen, aber das funktioniert auch nicht. Ich habe Value 
auch schon als signed char argument angegeben, aber das hat auch nicht 
geklappt.

Geschrieben mit AVR-Studio mit WinAVR-Plugin für Atmega1281

Der Wert *tast kommt von einem Inkrementalgeber und kann nur die Werte 
0, 1 und -1 annehmen.
1
void fnFunction (char *tast, unsigned char *value, unsigned char max)
2
{
3
  char temp = (char)*value;  
4
5
  temp += *tast;  
6
7
  if(temp < 0){  //damit gehts nicht
8
     temp = 0;  
9
  }
10
        /*
11
        if(temp > 200){  //damit gehts
12
          temp = 0;  
13
        }*/
14
  else if(temp >= max){  
15
     temp = max-1;
16
  }
17
  
18
  *value = temp;
19
  *tast = 0;
20
}

Woran kann das liegen?
Ich bin echt verzweifelt. Besonders wegen meines Unwissens.

Vielen Dank schon mal für eure Hilfe!

MfG Paul

von Melanie G. (Gast)


Lesenswert?

Paul P. schrieb:
> /*
>
>         if(temp > 200){  //damit gehts
>
>           temp = 0;
>
>         }*/

wundert mich, da temp ein signed char ist und somit nur bis 128 gehen 
kann...

von Peter (Gast)


Lesenswert?

ich denke ein char ist weder unsigned noch signed. Man sollte sich also 
nicht darauf verlassen.

nimmer lieber

uint8_t bzw int8_t

von Melanie G. (Gast)


Lesenswert?

Außerdem bringst Du da gewaltig signed und unsigned durcheinander...

von Floh (Gast)


Lesenswert?

Komische Denkansatz. Du willst, wenn ich das richtig verstehe, einen 
Überlauf positiv (255->0) wie negativ (0->255) verhindern?
Dann würd ich das so machen:
Der Wert wird nur verändert, wenn ich nicht am Rand bin, also:

{
if(*tast < 0)
  if(*value != 0)
    (*value)--;

if(*tast > 0)
  if(*value != 255)
    (*value)++;
}

:-)

von Paul P. (dorpreuss)


Lesenswert?

@Melanie:
Mich wundert das auch, aber trotzdem funktioniert es.

Das komische ist ja gerade, dass (temp>200) funktioniert und (temp<0) 
nicht.

Wieso bringe ich signed und unsigned durcheinander?

@Peter:
Ich würde das auch machen, aber da funktioniert das Highlighting nicht 
mehr und das stört mich.

@Floh:
Ich will keinen positiven Überlauf abfangen sondern nur, dass der Wert 
auf den Maximalwert begrenzt wird. Der Maximalwert ist höchstens 20.
Den negativen Überlauf will ich allerdings wirklich abfangen. Das soll 
eine Menüsteuerung werden und ich will, dass das Menü nicht durchläuft, 
sondern beim höchsten bzw. niedrigsten Menüeintrag stehen bleibt.

von Paul P. (dorpreuss)


Lesenswert?

Haha, ich werd irre!

Ich habe jetzt gerade vor alle char ein signed geschrieben. Jetzt 
funktioniert es. Es reicht jetzt auch ein cast von *value und ich 
brauche temp nicht mehr.

Damit habe ich einfach nicht gerechnet. Ich dachte char ohne "signed" 
ist automatisch signed. Jetzt weiß ich es besser. So ein dümmlicher 
Anfängerfehler.

Vielen Dank für eure Hilfe, speziell an Peter.

MfG Paul

von Floh (Gast)


Lesenswert?

Paul P. schrieb:
> Ich will keinen positiven Überlauf abfangen sondern nur, dass der Wert
> auf den Maximalwert begrenzt wird. Der Maximalwert ist höchstens 20.
> Den negativen Überlauf will ich allerdings wirklich abfangen. Das soll
> eine Menüsteuerung werden und ich will, dass das Menü nicht durchläuft,
> sondern beim höchsten bzw. niedrigsten Menüeintrag stehen bleibt.

Dann so:

Floh schrieb:
> if(*tast < 0)
>   if(*value > 0)
>     (*value)--;
>
> if(*tast > 0)
>   if(*value < max)
>     (*value)++;

:-) Dann sind die Datentypen relativ egal. Das Problem bei deiner Lösung 
sind die unterschiedlichen Effekte bei der Nullunterschreitung (signed 
-> -1, unsigned auf 255).

von Paul P. (dorpreuss)


Lesenswert?

Eben, deshalb hatte ich das ja geschrieben: if(temp > 200), das liefert 
in diesem Fall das gleich Ergebnis wie if(temp < 0) bei signed.

Is ja auch egal, Problem gelöst.

Ich habe eben im Verzeichnis von WinAVR nach einer Liste mit Keywords 
gesucht und tatsächlich eine gefunden. In der Datei: AvrStudio_c.ini 
habe ich die Typen uint8_t, int8_t usw. hinzugefügt. Jetzt funktioniert 
das Syntax Highlighting auch bei diesen Typen. Geil

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.