Frage zum "guten" Programmierstil bzgl uint8_t

Gast #599954
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
#599959
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.
Gast #599962
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
#599994
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...
Gast #600346
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:
1
if (time->hour<23) time->hour++; else time->hour=0;
2
if (time->hour>0) time->hour--; else time->hour=23;

Gruß und Danke

Andreas
Moderator Persönliche Seite #600758
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?
Gast #600922
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.
#601086
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
#601090
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
Gast #601134
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

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