Ich versuche gerade von BASCOM auf C umzusteigen. Habe eine kleines Unterprogramm geschrieben, welches eine Integerzahl über den UART ausgibt: void print_char (char c) { while (!(UCSRA & (1<<UDRE))){} UDR = c; } void print_int (int wert) { int temp; int i; for (i=0; wert!=0; i++) { temp = wert % 10; temp += 48; print_char(temp); wert /= 10; }; } Das Funktioniert auch, allerdings werden die Stellen falsch herum (also mit der kleinste Stelle zuerst ausgegebne). Ich könnte zwar die einzelnen Stellen in ein ARRAY schreiben und dann, falsch herum ausgeben. Gibt es vielleicht eine eleganter Methode dafür?
Kernighan & Ritchie Die haben ein Buch namens "The C-Programming language" geschrieben. Es ist quasi die C-Bibel...
>Gibt es vielleicht eine eleganter Methode dafür?
Die meisten Compiler (z.B. avr-gcc) haben eine Funktion "itoa" mit in
Ihrer C-Bibliothek, die solltest Du Dir mal anschauen...
Ist schon klar, aber die Funktionen sind meistens sehr groß. Selber machen ist doch viel schöner. Dann kann ich ja gleich bei BASCOM bleiben.
Könntest auch Subtraktions-Methode nehmen: Mit größter Zehnerpotenz anfangen, bei 3567 als Wert z.B. 1000:
1 | int minuend = 1000; |
2 | char temp = 0; |
3 | while (zahl > minuend) |
4 | {
|
5 | zahl -= minuend; |
6 | temp++; |
7 | }
|
8 | temp += 48; |
Das packste entweder in ne Schleife und jeden Schleifendurchgang minuend / 10 oder du machst es halt 4-5x mit konstanten Minuenden.. ich hoffe, das Ding heißt auch Minuend ;)
Entweder Du nimmst ein Array fuer die Zwischenspeicherung oder du machst eine rekursive Funktion: void print_int_help (int wert) { if( wert == 0 ) return; int temp = wert % 10; print_int_help( wert / 10 ); print_char( temp + '0' ); } void print_int( int wert ) { if( wert == 0 ) print_char( '0' ); else print_int_help( wert ); } Rekursive Funktionen werden in µC Programmierung nicht sehr gerne gesehen, da sie alles am Stack abwickeln und der ist meist eher knapp.
Besser als "itoa" gefällt mir für solche Zwecke die Funktion "sprintf", die genauso wie printf arbeitet, allerdings ihr Ergebnis in eine anzugebenden (und ausreichend großen) String schreibt. Damit kann man nicht nur die Zahl wandeln, sondern auch gleich noch was zu deren Bedeutung schreiben (muss man aber nicht ;). Gruß Konrad
Das ist aber völlig konträr zu Pets vorhaben, den Code so klein als möglich zu machen. "printf" ist ein Speicherfresser.
Das is schon klar, nur liest das hier vielleicht auch noch jemand anderes, der genau sowas gesucht hat - währe aufgrund des Thread-Titels ja immerhin denkbar ;)
Danke für eure Antworten. Ich habe es jetzt doch so wie ich es am Anfang geschrieben habe realisiert. Speicher jetzt jede Stell im Array ab und gib es dann wieder Rückwerts aus. Ist am einfachsten, auch wenn es vielleicht eleganter geht.
Hier noch der Code void print_char (unsigned char c) { while (!(UCSRA & (1<<UDRE))); UDR = c; } void print_uint (unsigned int wert) { unsigned char ziffer[5], anz=0,x; do { ziffer[anz++] = wert % 10 + 48; } while (wert /= 10); for (x=anz; x!=0; x--) print_char(ziffer[x-1]); print_char (13); //Carriage return print_char (10); //line feed }
Das einzige was ich Dir ans Herz legen moechte, ist: Gewoehn Dir schnell wieder ab, Zeichen durch ihren ASCII Code auszudruecken: wert % 10 + 48 ist (bei ASCII) absolut equivalent zu: wert % 10 + '0'; nur dass man im zweiten Fall besser sieht, was da passiert. Du willst das Ergebnis der modulo Division so bearbeiten dass ein integer von 0 das Zeichen '0' ergibt, 1 zum Zeichen '1' wird. usw. Im Originalcode ist das nicht so offensichtlich. Spaetestens nach 2 Wochen raetselst Du herum: Warum 48, warum 48, warum 48? Bis es Dir dann wieder wie Schuppen aus den Haaren faellt: Der ASCII Code von '0' ist 48. Selbiges fuer 13 und 10 13 ist '\r' Carriage return 10 ist '\n' line feed Schreibst Du: print_char( '\r' ); print_char( '\n' ); dann kannst Du Dir auch die Kommentare sparen. Jeder der C kann, sieht im Code, und nicht im Kommentar, dass hier Carriage Return und Line Feed ausgegeben wird. Code sollte immer selbstkommentierend sein.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.