Compilerwarnung gcc
-
Wenn ich mein Programm
char dezimal2ziffer(unsigned char dezimal) { char ziffer = 0; if (dezimal >= 0 && dezimal < 10) { int i = 0; int j = 48; while (dezimal != i) { ++i; ++j; } ziffer = j; return ziffer; } if (dezimal >= 10 && dezimal <= 35) {...} if (dezimal >= 36 && dezimal <= 61) {...} int main() { unsigned char dezimal = 8; //nur zum testen printf("\nErgebnis: %c", dezimal2ziffer(dezimal)); return 0; }
(Dezimalzahlen in Ziffern für die b-adische Darstellung umrechnen z.B. 10->A)
mit
gcc -ansi -pedantic -W -Wall -Wextra -c programm.c
kompiliere, bekomme ich die Warnung
programm.c: In function 'dezimal2ziffer': programm.c:65:2: warning: comparison is always true due to limited range of data type [-Wtype-limits] if (dezimal >= 0 && dezimal <= 9) ^
Die Warnung kommt nur für die erste if Anweisung und ich verstehe absolut nicht warum...unsigned char geht doch von 0-255..?
Schonmal danke im Voraus:)
-
KJoke schrieb:
Die Warnung kommt nur für die erste if Anweisung und ich verstehe absolut nicht warum...unsigned char geht doch von 0-255..?
Es bezieht sich auf den Teilausdruck
dezimal >= 0
.
-
Ok dann gibt das ganze Sinn, danke
also dann nurif (dezimal < 10)
-
Ich weiß ja nicht was du da vor hast, aber für die eine Ziffer reicht
if (dezimal < 10) return '0' + dezimal;
Das macht alles, was du in den Zeilen 4 bis 15 machst.
-
KJoke schrieb:
(Dezimalzahlen in Ziffern für die b-adische Darstellung umrechnen z.B. 10->A)
Ok, jetzt habe ich es gesehen.
Du darfst statt der '0' auch 'A' oder ein anderes Zeichen schreiben.
Willst du zwischen Groß-und Kleinschreibung unterscheiden?
-
Oh stimmt, ich denke da wohl etwas zu umständlich
----
0-9 -> 0-9
10-35 -> A-Z
36-61 -> a-z
also bis Basis 62funktioniert bei den anderen genauso, nur muss ich noch 7 bzw. 13 draufaddieren
-
if (dezimal < 62) return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[dezimal];
oder, da wir davon ausgehen können, dass Nutzereingaben vorher gefiltert werden und der allwissende Programmierer natürlich niemals eine Funktion mit falschen Argumenten aufrufen würde
:
return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[dezimal];
-
KJoke schrieb:
funktioniert bei den anderen genauso, nur muss ich noch 7 bzw. 13 draufaddieren
Da schreibst du besser
return 'A' + dezimal - 10; // bzw. return 'a' + dezimal - Selber_rausfinden;
Oder
const char digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; if (dezimal < strlen(digits)) // In der Hoffnung, dass der Compiler das in einen Konstanten Ausdruck optimiert. return digits[dezimal];
Dann klappt das auch, wenn in dem Code die Buchstaben nicht lückenlos hintereinander liegen. Z.B bei EBCDIC
-
@DirkB, dir ist ein kleiner Fehler unterlaufen. Du hast einen sehr großen (oder langen) char
-
Das passiert, wenn man den Code vorher nicht testet.
const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
Aber wäre dann die Methode ohne String nicht die bessere?...Zumindest wird mir momentan beigebracht, möglichst wenige Variablen zu verwenden bzw. sparsam mit dem Speicher umzugehen, auch wenn das in dem Rahmen kaum einen Unterschied macht
-
Du kannst Zeit durch Speicher einsparen. Oder umgekehrt.
Wenn du nicht gerade auf Mikrokontrollern unterwegs bist, spielt der Speicher keine Rolle.
Und gegenüber deinem ersten Code ist das ein Platzsparwunder. :p
-
Ein Zeichenkettenliteral ist keine Variable im Programm. Das steht irgendwo ein einziges Mal fest im Programmcode. Was technisch gesehen das Programm um ein paar Byte vergrößert, ja. Dafür wird jedoch aus einer relativ komplizierten Funktion mit vielen Verzweigungen eine einfache Addition und ein Zugriff. Wodurch das Programm wieder kleiner wird. Und vor allem schneller, weil viel weniger Code ausgeführt wird (gerade Verzweigungen wiegen oft schwer).
-
Ja stimmt wohl, mein Code war ein ziemliches Ungetüm
Achso ok..was wie effizient ist kam in meinen Vorlesungen leider noch nicht wirklich dran
Danke für die Antworten!