Moin,
eigentlich ist mir das ja schon fast peinlich, aber...
1
uint32_tEngine_Speed=0;
2
3
Engine_Speed=(int)Engine_Speed;
4
sprintf(buf1,"%i",Engine_Speed);
obwohl ich brav gecasted habe bekomme ich eine Warnung:
Warning 1 format '%i' expects argument of type 'int', but argument 3
has type 'uint32_t' [-Wformat]
int Engine_Speed = 0; anstatt uint32_t Engine_Speed = 0;
geht wie üblich fehlerfrei.
uint32_t Engine_Speed = 0;
Engine_Speed = (int)Engine_Speed;
sprintf( buf1,"%i", Engine_Speed);
klar ist das falsch,
Engine_Speed = (int)Engine_Speed;
Engine_Speed bleibt uint32_t, du wandelst nur Engine_Speed in (int) und
dann wieder in uint.
Wenn du dies machst:
sprintf( buf1,"%i", (int)Engine_Speed);
dann gibt der Compiler keinen Fehler aus, aber eigentlich gibt es auch
unsigned int für (s)printf und eigentlich solltest du dies verwenden.
>du musst eine int variable deklarieren. und dieser dann denn gecasteten>Wert zuweisen
Mach ich das denn nicht mit der Zeile:
uint32_t Engine_Speed = 0;
?
>Hallo,>mach den cast doch in der Ausgabe.
Warnung ist weg. Danke.
>aber eigentlich gibt es auch>unsigned int für (s)printf und eigentlich solltest du dies verwenden.
sprintf( buf1,"%ui", Engine_Speed);
>Das geht nicht, gleiche Warnung. System hier ist 32-bit.
>>du musst eine int variable deklarieren. und dieser dann denn gecasteten>>Wert zuweisen>Mach ich das denn nicht mit der Zeile:>uint32_t Engine_Speed = 0;>?
Nein du deklarierst einen 'uint_32t' das ist nicht das gleiche wie 'int'
Joachim ... schrieb:> uint32_t Engine_Speed = 0;>> Engine_Speed = (int)Engine_Speed;
Das ändert aber nichts.
Die Variable Engine_Speed ist auch danach immer noch vom Datentyp
uint32_t
Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der
Defintion der Variablen und behält ihn danach bei, bis sie zerstört
wird. Du kannst diser Variablen zuweisen was du willst, das ändert
nichts daran, dass die Variable (bei dir) ein uint32_t ist. Alles was du
zuweist wird automatisch immer zu einem uint32_t. Denn so ist die
Variable ja definiert. In C passen sich die Datentypen von Variablen
nicht an das an, was man ihnen zuweist. Sonst bräuchte man ja von vorne
herein Variablen überhaupt keinen Datentyp geben, wenn das dann sowieso
dadurch geregelt wird, was ihnen zugewiesen wird.
Dann hat dein Compiler ein Problem,
Engine_Speed=100;
sprintf( buf1,"%ui", Engine_Speed);
Ausgabe wäre 100i !!!
dies ist das richtige:
sprintf( buf1,"%u", Engine_Speed);
>Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der>Defintion der Variablen und behält ihn danach bei, bis sie zerstört>wird.
Ok, ich glaub wir haben jetzt eine Lücke in meinem Kopf geschlossen.
D.h. also, in
sprintf( buf1,"%i", (int)Engine_Speed);
wird "nur zur Übergabe" aus dem uint32_t ein int.
Joachim ... schrieb:>>Hallo,>>mach den cast doch in der Ausgabe.> Warnung ist weg. Danke.
Ist eigentlich der falsche Weg.
Benutze in der Format Liste die richtigen Kürzel, die zu den Datentypen
der Argumente passen und nicht umgekehrt caste die Argumente so zurecht,
so dass sie zur Format-Liste passen.
Einen Cast sollte man nur dann verwenden, wenn es keine andere
Alternative gibt. Ein Cast ist immer die schlechteste Möglichkeit, ein
Problem zu lösen. Casts sind sozusagen der Holzhammer, mit dem man alles
irgendwie passend machen kann - egal ob das nun richtig ist oder nicht.
Joachim ... schrieb:>>Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der>>Defintion der Variablen und behält ihn danach bei, bis sie zerstört>>wird.>> Ok, ich glaub wir haben jetzt eine Lücke in meinem Kopf geschlossen.> D.h. also, in> sprintf( buf1,"%i", (int)Engine_Speed);> wird "nur zur Übergabe" aus dem uint32_t ein int.
Exakt.
Und das auch nur, weil du das so befohlen hast, damit dieser int zum %i
passt.
Würdest du umgekehrt vorgehen und dich fragen welchen Datentyp
Engine_Speed hat, dann stellst du fest, dass das ein uint32_t ist, auf
deinem System wohl ein unsigned long. Ergo brauchst du anstelle des %i
das entsprechende Kürzel welches zu einem unsigned long passt.
Hmm. Also die beiden Zeilen hier:
Engine_Speed=100;
sprintf( buf1,"%u", Engine_Speed);
werfen für die Zeile mit sprintf:
Warning 1 format '%u' expects argument of type 'unsigned int', but
argument 3 has type 'uint32_t' [-Wformat]
Aber wir kommen hier langsam vom Stöckchen zum Zeigchen und sollten das
Ganze allmählich wegen Geringfügigkeit abbrechen...
Joachim ... schrieb:> Aber wir kommen hier langsam vom Stöckchen zum Zeigchen und sollten das> Ganze allmählich wegen Geringfügigkeit abbrechen...
Du würdest wesentlich schneller vorankommen, wenn du ein C-Buch hättest.
Denn da wäre eine Tabelle drinnen, in der die ganzen % Specifier
aufgeschlüsselt sind. Und nebenbei noch 300 andere Dinge, die man mit
dem Format-String so anstellen kann.
1
sprintf(buf1,"%ul",Engine_Speed);
Aber ... du bist nicht der erste, du bist nicht der letzte und du wirst
auch nicht der letzte sein, der denkt, man könne C mit anlassbezogenem
Zusammenfragen von Achtelwissen in einem Forum vernünftig lernen. Das
hat noch nie funktioniert, das funktioniert nicht und das wird auch nie
funktionieren.
Was mich an der ganzen Diskussion ein wenig vermisse:
Hat denn auf Deinem µC ein "int" die gleiche Bitbreite wie ein
"int32_t"?
Hat denn auf Deinem µC ein "unsigned int" die gleiche Bitbreite wie ein
"uint32_t"?
Auf meinem PIC24 kann ich mit %i nur 16Bit-Werte ausgeben,aber kein
int32_t.
Karl Heinz Buchegger schrieb:> dass das ein uint32_t ist, auf> deinem System wohl ein unsigned long. Ergo brauchst du anstelle des %i> das entsprechende Kürzel welches zu einem unsigned long passt.>> sprintf( buf1,"%ul", Engine_Speed);
Man benutzt Datentypen wie uint32_t ja aber auch, um sich von
Plattformabhängigkeiten zu befreien. Sich diese über printf-Specifier
durch die Hintertür wieder rein zu holen, finde ich nicht sehr sinnvoll.
Und es gibt schließlich einen standardisierten Weg, die
Plattformunabhängigkeit auch in die printf-Specifier zu übertragen:
1
sprintf(buf1,"%"PRIu32,Engine_Speed);
Man mag über die Ästhetik streiten, aber es ist nun mal der vorgesehen
Weg, der (meiner Meinung nach) auch Neulingen nahe gebracht werden
sollte.
Stefan Ernst schrieb:> Plattformunabhängigkeit auch in die printf-Specifier zu übertragen:>
1
sprintf(buf1,"%"PRIu32,Engine_Speed);
> Man mag über die Ästhetik streiten, aber es ist nun mal der vorgesehen> Weg, der (meiner Meinung nach) auch Neulingen nahe gebracht werden> sollte.
Full Ack.
Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)
Mea culpa.
Karl Heinz Buchegger schrieb:> Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)Karl Heinz Buchegger schrieb:> sprintf( buf1,"%ul", Engine_Speed);
Die alten aber auch nicht. :-)
Es ist "%lu"
u ist das Ausgabeformt
l ist die Größenangabe
DirkB schrieb:> Karl Heinz Buchegger schrieb:>> Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)>> Karl Heinz Buchegger schrieb:>> sprintf( buf1,"%ul", Engine_Speed);>> Die alten aber auch nicht. :-)> Es ist "%lu">> u ist das Ausgabeformt> l ist die Größenangabe
Ich darf Homer Simpson zitieren: Mist
Da kannst du mal sehen, wie oft ich noch uint32_t und printf zusammen
verwende. :-)
Auf jeden Fall danke für die Korrektur.
Rene H. schrieb:> uint32_t != int>> uint32_t = unsigned> int = signed
Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int"
signed ist? Und ist das auch in der Praxis immer so? Gibt es Compiler
wo "int" einem "unsigned int" entspricht (oder das per Compiler-Option
so eingestellt werden kann)?
Ich weiss, dass "char" sowohl signed als auch unsigned sein kann, z.T.
als Compileroption auswählbar, oder dass z.B. manche Compiler per Option
erlauben, dass "int" als "short" behandelt wird, usw. Daher meine Frage.
asdf schrieb:> Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int"> signed ist? Und ist das auch in der Praxis immer so? Gibt es Compiler> wo "int" einem "unsigned int" entspricht (oder das per Compiler-Option> so eingestellt werden kann)?
Das kann ich nicht mit absoluter Sicherheit sagen, aber meines Wissens:
ja. Und ich kenne keinen Compiler der aus int einen unsigned macht.
Grüsse,
René
asdf schrieb:> Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int"> signed ist?
Ja, außer wenn int der Type eines Bitfelds ist. In diesem Fall ist es
implementation-defined, ob int überhaupt erlaubt ist und wenn ja, ob
der Typ vorzeichenbehaftet ist. Im Standard spezifiziert sind nur die
Bitfeldtypen _Bool, signed int und unsigned int.