char_p[i]=(zahl%10)+'0';// Modulo rechnen, dann den ASCII-Code von '0' addieren
8
zahl/=10;
9
}
10
}
11
12
intmain(void){
13
// 0 1 2 3
14
unsignedcharchar_a[4]={'1','0','2','3'};
15
unsignedinttest_int=3201;
16
while(1){
17
my_uitoa(test_int,char_a,3);
18
SerWrite(char_a,4);
19
// Deklaration von SerWrite(unsigned char* char_p, unsigned char byte_cnt);
20
}
21
return0;
22
}
Aber leider tut das Programm nicht was es soll! Bzw. es tut gar nix, ich
habe versucht hinter dem Funktionsaufruf eine LED zu schalten, so weit
kommt er schon nicht mehr.
Benutze ich SerWrite ohne Aufruf von my_uitoa funktioniert die Ausgabe..
also muss der Fehler irgendwo in der Funktion my_uitoa oder im Auruf
liegen.. aber ich habe gerade Tomaten auf den Augen und finde den Fehler
nicht..
hab auch schon den Start parameter weggelassen... der soll später (wenns
mal funktioniert) dazu dienen an verschiedene Stellen in einem string zu
schreiben..
Achja und den /0 Terminator im String brauche ich auch nicht.. wie
gesagt funktioniert der Aufruf von SerWrite ohne my_uitoa...
VIELEN DANK!!
kopf kratz
Den Hinweis versteh ich gerade nicht...
Der Schleifenzähler sollte ja auf jeden fall signed sein.. sonst bricht
die schleife ja nie ab.
Wo habe ich einen signed/unsigned Fehler ???
DANKE !!!
Du übergibst der Funktion einen Zeiger (unsigned char* char_p),
versuchst in der Funktion aber, diesen als Array zu bearbeiten
(char_p[i]=(zahl % 10) +'0';). Du musst da schon den Zeiger
dereferenzieren.
Abgesehen davon solltest Du Dir direkt angewöhnen, ASCII-Strings in C
auch zu terminieren, da Du sonst irgendwann mal Probleme bekommen wirst,
wenn Du Bibliotheksfunktionen zur Stringverarbeitung bzw. Stringausgabe
verwenden willst, die alle mit nullterminierten Strings arbeiten.
> unsigned char char_a[4] = {'1','0','2','3'};
Das sollte man übrigens auch nicht machen. ASCII-Zeichen (Textzeichen)
sind in C grundsätzlich vom Typ char und nicht unsigned char. Auch,
wenn es jetzt nur für Deine eigenen Anwendungsfälle ist, gewöhne es Dir
aus o.g. Gründen gleich richtig an.
noch mehr am kopf kratz
unsigned char* char_p
ist doch ein Pointer auf (unsigned char) ? Ja, oder net?
und mit char_p[i] wird der Zeiger doch dereferenziert ???
(adresse = &(char_p[0]) + (i * sizeof(unsigned char)) verwirrt bin
Oder habe ich da nen grundsätzlichen Denkfehler drin ???
Johannes M. wrote:
> Du übergibst der Funktion einen Zeiger (unsigned char* char_p),> versuchst in der Funktion aber, diesen als Array zu bearbeiten> (char_p[i]=(zahl % 10) +'0';). Du musst da schon den Zeiger> dereferenzieren.
Er dereferenziert ihn doch mit "[]". Das ist völlig ok so.
Johannes M. wrote:
> Du übergibst der Funktion einen Zeiger (unsigned char* char_p),> versuchst in der Funktion aber, diesen als Array zu bearbeiten> (char_p[i]=(zahl % 10) +'0';). Du musst da schon den Zeiger> dereferenzieren.
Nein, muss man nicht. Das funktioniert auch so.
Ich würde anstelle von
char i;
besser
signed char i;
schreiben, denn char ist nicht immer als signed definiert, das hängt
etwas von den Compilereinstellungen ab. Und wenn start dann <3 ist, dann
kann es sein, dass die Schleife ewig läuft.
> for(i=start; i>=(start-3); i--) {
Es ist schlecht, den Compiler entscheiden zu lassen, welche Datentypen
er nehmen darf.
Was kommt das wohl raus?
... i>=(start-3) ... --> ein Vergleich signed mit unsigned
Ich würde den wenigstens Casten, dass der Compiler nicht beliebig
kreativ sein kann:
for(i=start; i>=((char)start-3); i--) {
Oder gib deiner Funktion als Parameter einfach mal
my_uitoa(test_int,char_a, 2 );
Was passiert jetzt?
high-side wrote:
> Wo habe ich einen signed/unsigned Fehler ???
Hier:
1
chari;// schleifenzähler
2
3
for(i=start;i>=(start-3);i--){
Ob ein char signed oder unsigned ist, liegt im Ermessen des Compilers.
Bei unsigned kann die Schleife aber ganz schnell zur Endlosschleife
werden (z.B. bei deinem start=3).
Also:
char i;
->
signed char i;
Du hast schon Recht, dass ich mit Strings anders umgehen sollte... aber
der Code sollte doch trotzdem funktionieren ???
ich will ja nur bytes übertragen.. wie gesagt erwartet die
Übertragungsfunktion SerWrite keinen terminierten String sondern einfach
Bytes... aber soweit kommt er ja leider gar net.... :-(
Du meinst ich muss hier explizit signed angeben ??? ich dachte char wäre
von natur aus schon ein vorzeichenbehafteter Wert ???
Der Controller ist ein ATMEGA8 ...
Hallo,
ich denke, dass das Problem in der Abbruchbedingung liegt. Hier wird
unsigned char mit signed char verglichen, was im Falle 3 dazu führt,
dass unsigned char immer größer gleich 0 und damit immer wahr ist.
Gruß
Torsten
high-side wrote:
> Du meinst ich muss hier explizit signed angeben ???
Ja.
> ich dachte char wäre> von natur aus schon ein vorzeichenbehafteter Wert ???
Nein, nicht notwendigerweise.
@lothar:
ich werde das mit 2 und dem cast mal ausprobieren...
jetzt bin ich aber mal gespannt....
dachte das "char i" hier schon die größte Stolperfalle gewesen wäre ;-)
... über die ich auch schon gestoplert bin.. dann dachte ich JA das
wars! Wars aber leider anscheinend doch nicht.... :-(
Danke an alle!
8 Bit können so gemein sein... ;-)
> 8 Bit können so gemein sein... ;-)
Pass mir ja auf das Bit auf, das ist noch so klein ;-)
> ich werde das mit 2 und dem cast mal ausprobieren...
Wenn du das machst gibt es einen amoklaufenden Pointer (wg. Index = -1).
Nein, du solltest das nur Durchdenken.
Kleiner Tip am Rande: Die stdint.h enthält eine ganze Reihe
easy-to-use-Typdefinitionen (auch 8-Bit-Typen), die eindeutig benannt
sind und bei denen es folglich keine derartigen Probleme gibt. Bau die
stdint.h ein und mach es mit int8_t (bzw. im anderen Fall mit uint8_t).
Lothar Miller wrote:
>> ich werde das mit 2 und dem cast mal ausprobieren...> Wenn du das machst gibt es einen amoklaufenden Pointer (wg. Index = -1).> Nein, du solltest das nur Durchdenken.
Oder was in die gleiche Kerbe schlägt
1
for(i=start;i>=(start-3);i--){
Huch, wieso 3? Wo kommen diese 3 her? Was bedeuten sie?
Warum nicht 4 oder 5? Welche Implikationen hat das für die
möglichen Werte in start?
und denk drann:
Wenn in einem Ausdruck sowohl signed als auch unsigned Werte vorkommen,
wird alles nach unsigned gewandelt!
i ist bei dir signed
start ist unsigned
-> Für den Vergleich wird alles nach unsigned gewandelt.
Aber: Als unsigned ausgedrückt, kann i nie den Wert -1 haben!
Der wär aber nötig, wenn start den Wert 3 hat, denn 3 - 3 macht 0
und damit die Schleife abbrechen kann muss i kleiner als 0 werden.
i wird zwar kleiner als 0, aber nicht während des Vergleichs. Während
des Vergleichs wird i als unsigned Wert angesehen und als unsigned
gesehen kann i per Definition nicht negativ werden.
Ob CHAR mit oder ohne Vorzeichen ist, kann man dem GCC per
Kommandozeilenargument verklickern.
Besser ist in jedem Fall int8_t, der ist immer mit Vorzeichen.