www.mikrocontroller.net

Forum: Compiler & IDEs Verzweigung bei Wert kleiner 0


Autor: Paul P. (dorpreuss)
Datum:

Bewertung
0 lesenswert
nicht 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.
void fnFunction (char *tast, unsigned char *value, unsigned char max)
{
  char temp = (char)*value;  

  temp += *tast;  

  if(temp < 0){  //damit gehts nicht
     temp = 0;  
  }
        /*
        if(temp > 200){  //damit gehts
          temp = 0;  
        }*/
  else if(temp >= max){  
     temp = max-1;
  }
  
  *value = temp;
  *tast = 0;
}

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

Vielen Dank schon mal für eure Hilfe!

MfG Paul

Autor: Melanie G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter (Gast)
Datum:

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

nimmer lieber

uint8_t bzw int8_t

Autor: Melanie G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem bringst Du da gewaltig signed und unsigned durcheinander...

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)++;
}

:-)

Autor: Paul P. (dorpreuss)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Paul P. (dorpreuss)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Paul P. (dorpreuss)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.