mikrocontroller.net

Forum: Compiler & IDEs Frage zum "guten" Programmierstil bzgl uint8_t


Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

Ich habe in meinem aktuellen Projekt alle (betroffenen) Variablen als 
uint8_t deklariert. In diesen Variablen halte ich Tage, Stunden, Minuten 
und Sekunden einer Uhr. Diese Werte bewegen sich zwischen 0 und maximal 
59.

Bei Einstellen der Uhr tritt u.U. der Fall auf, dass z.B. die Minuten 
per Default auf "00" stehen, die Aktuelle Zeit aber "50" Minuten ist. 
Beim Stellen müsste nun 50x auf den "Minuten+"-Taster gedrückt werden um 
die korrekte Zeit zu stellen. Einfacher wäre es doch den 
"Minuten-"-Taster 10x zu drücken.

Beim ersten Schleifendurchlauf (Minuten auf "00") würde der Druck auf 
"Minuten-" eine negative Zahl produzieren. Da meine Variablen aber als 
"uint8_t" und damit "unsigned" deklariert sind, ändert sich der Wert auf 
255, was in diesem Fall korret ist.

Im Moment habe ich als "Hack" eine Abfrage erstellt, die prüft ob der 
Wert der Minuten-uint8_t-Variable >200 ist. In diesem Fall setze ich die 
Variable auf 59.

Ist das Euerer Meinung nach, im Sinne eines guten, lesbaren 
Programmierstils Ok oder würdet Ihr wegen dieser "Kleinigkeit" das 
gesamte Programm überarbeiten und von uint8_t weggehen auf int8_t. Was 
diverse andere Probleme (casts etc.) mit sich bringen würde ???

Gebt mir bitte mal Euere Meinung ...

Gruß

Andreas

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da die Arithmetik von vorzeichenlosen Typen in C erstens erstens ohne 
Overflow-Trap und zweitens als Modulo-Arithmetik definiert ist, gibt es 
damit m.E. keine Probleme. Bei Typen mit Vorzeichen ist so etwas 
hingegen undefiniert.

Eleganter wär's allerdings, du würdest auf 0 testen, bevor du 
runterzählst.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guter Programmierstil ist es, alle Benutzereingaben auf gültige Werte zu 
überprüfen, und auf sinnvollen Werte zu begrenzen.

Also gehören da Abfragen rein, die den Übergang von 59 auf 0, und 
ungekehrt behandeln.

Oliver

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Abfrage ob = 0 kann man sich doch sparen, wenn man die Variable nach 
dem Inkrementieren/Dekrementieren mit "% 60" behandelt.
Dadurch wird der Zahlenbereich auf Zahlen zwischen 0 und 59 begrenzt.
Da eine unsigned Variable benutzt wird, kommmt es zu einem Überlauf beim 
Übergang von 0 auf -1 (bzw. 255). Wenn man dann 255 % 60 rechnet sollte 
59 herauskommen (kann aber auch sein, dass da was anderes bei 
rauskommt...).

Ob eine Abfrage nicht schneller wäre, sei dahingestellt...

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

keine gute Idee da 255 % 60 = 15
Wenn der Tastendruck "Minuten-" kommt einfach die Variable auf 0 prüfen 
und falls der Vergleich wahr ist Minuten auf 59 setzen sonst eben 
Minuten--. Für "Minuten+" dann analog und fertig.

Matthias

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Weißer wrote:
> keine gute Idee da 255 % 60 = 15

Ist doch unwichtig.
SekundenHoch()
{
  sekunden = (sekunden + 1) % 60;
}

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuche immer so einfach wie möglich das Thema abzuhandeln. Der 
entscheidende Tipp kam von Oliver - vielen Dank dafür!

Ich habe es wie folgt gelöst:
if (time->hour<23) time->hour++; else time->hour=0;
if (time->hour>0) time->hour--; else time->hour=23; 

Gruß und Danke

Andreas

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon:

Eine Divisionsroutine verwenden, nur um den Bereich einer 
Minuten/Sekunden-Variable einzugrenzen? Finde ich etwas Overkill, zumal 
% 60 ja nicht mit Bitmaskiererei/-schieberei realisiert werden kann...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Philipp Burch wrote:
> @Simon:
>
> Eine Divisionsroutine verwenden, nur um den Bereich einer
> Minuten/Sekunden-Variable einzugrenzen? Finde ich etwas Overkill, zumal
> % 60 ja nicht mit Bitmaskiererei/-schieberei realisiert werden kann...

Hey! Ich kam nicht auf die Idee ;) ;)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum nimmst du nicht int8_t?  Dein gewünschter Wertebereich passt
ja da noch ordentlich hinein, und du kannst danach ganz legal auf
-1 testen.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was bei unsigned Byte 255 wäre. Entweder auf < 0 oder > 59 nach dem 
Dekremetieren überprüfen und falls es zutrifft +60 draufrechnen. So 
kannst du auch mit zb. 10 dekrementieren.

Gruß Hagen

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hagen Re wrote:

> was bei unsigned Byte 255 wäre.

Bei den meisten Implementierungen. ;-)

Im Ernst: die Portabilität ist nicht garantiert.

> ... auf < 0 ... nach dem
> Dekremetieren überprüfen

"Warning: comparision is always false due to limited data range."

Tu's nicht.  Auf > 59 prüfen geht sicher, aber ist ein Hack.  Wenn
man negative Zahlen erhalten kann, sollte man die Zahlen bitteschön
auch als vorzeichenbehaftet betrachten, warum ist das denn so
schlimm?

Autor: Bobby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie man einen Unsigned Datentyp auf kleiner 0 testen
kann ist mir unbekannt.

Teste daher immer vorher:
Beim Rückwärtszählen auf 0,
Beim Vorwärtszählen auf 59.

Zahlen > 59 bedeuten FEHLER, is klar.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Tu's nicht.  Auf > 59 prüfen geht sicher, aber ist ein Hack.  Wenn
>man negative Zahlen erhalten kann, sollte man die Zahlen bitteschön
>auch als vorzeichenbehaftet betrachten, warum ist das denn so
>schlimm?

Das bezog sich natürlich darauf das man entweder unsigned oder signed 
benutzt. Ich denke da exakt wie du, warum nicht int8_t benutzen dafür 
ist er da. Bei allem anderen würde ich meine Lehrlinge als Saboteure 
beschimpfen ;)

Mit zwei zugedrückten Augen würde ich vielleicht noch einen Typcast nach 
signed tolerieren, aber auch da wäre es besser gleich den richtigen 
Datentypen zu wählen.

Gruß Hagen

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie man einen Unsigned Datentyp auf kleiner 0 testen
>kann ist mir unbekannt.

indem man diesen hart casted nach signed. Die CPU selber kennt keinen 
signed oder unsigned Datentypen, für sie sind es binäre und 
komplementäre Zahlen, also sowohl unsigned wie auch signed. Erst die 
nachfolgenden Opcodes bei einem Vergleich, also die Auswertung der 
Flags, entscheidet ob man die vorherige Operation -> 
Subtraktion/Addition usw. als signed oder unsigned betrachtet. Aber in 
den Datentypen selber gibts diesen Unterschied nicht (vorrausgesetzt wie 
reden hier von generischen Datentypen die die CPU von Hause aus versteht 
und nicht von selbstgestrickten Datentypen).

Gruß Hagen

Autor: Bobby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann habe ich mich wohl etwas ungeschickt ausgedrückt.

Wenn ein unsigned Typ verwendet wird, dann
gibt es keine negativen Zahlen.

Natürlich kann man hintenrum sowas doch hinbekommen,
ist aber nicht die feine Art.

Ciao.

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.