Verzweigung bei Wert kleiner 0

OP #1822839
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
Gast #1822865
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)++;
}

:-)
OP #1822962
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.
OP #1822976
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
Gast #1822995
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).
OP #1823009
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren