Hallo, möchte gerne in einem c programm eine variable mit einem negativen wert laden. signed char variable; void main () { variable = -10; } geht das? Danke.
Ja, schon. Wirft aber die Frage auf, warum du den Quelltext nicht einfach in einen C-Compiler geworfen hast... der wüsste die Antwort auch.
Man benutzt globale Variablen aber nur in Ausnahmefällen und wer so ne Frage stellt, wird kaum in so ner Situation sein ;) Also deklarier deine Variable lokal in main, sonst wird dir irgendwann mal jemand anständig auf die Finger haun
Das "nein" bezog sich auf das vorhergehende. Also bei den Compilern kann man auch unsigned char für Strings erzwingen, aber normalerweise ist das ein 8-Bit Integer mit Vorzeichen.
char ist weder signed noch unsigned, sondern Umgebungsabhängig. Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen.
Sven P. schrieb: > char ist weder signed noch unsigned, sondern Umgebungsabhängig. Absolut richtig! > Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. Absolut falsch. Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann schaut man nicht in Header wie <stdint.h>, sondern verwendet die explizite Form "unsigned char" bzw. "signed char", dann läuft das Programm auch mit einem anderen Compiler nicht nur zufällig, sondern garantiert (jedenfalls dann wenn man nicht noch andere Compiler- und Plattformabhängigkeiten reinbaut ;-). Der Blick in Headerdateien ist meist der Anfang eines Fehlers. Gruß, Bernd
>> Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. > Absolut falsch. Wieso? > Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann > schaut man nicht in Header wie <stdint.h>, sondern verwendet die > explizite Form "unsigned char" bzw. "signed char", Was widerspricht Deiner Ansicht nach gegen uint8_t bzw. int8_t ?
Bernd O. schrieb:
> Der Blick in Headerdateien ist meist der Anfang eines Fehlers.
LOL.
So krass würde ich das nicht ausdrücken, aber in diesem speziellen Fall
hast du recht. Wenn es wichtig ist, ob char signed oder unsigned ist,
benutzt man keinen plain vanilla char sondern ist immer explizit bzw.
benutzt uint8_t bzw. int8_t.
Und zwar unabhängig davon ob char zufällig auf dem System schon die
richtige Signedness hat. Damit erübrigt sich dann auch das Nachsehen im
Headerfile.
Bernd O. schrieb: >> Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. > Absolut falsch. Was genau soll daran falsch sein? > Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann > schaut man nicht in Header wie <stdint.h>, sondern verwendet die > explizite Form "unsigned char" bzw. "signed char", dann läuft das > Programm auch mit einem anderen Compiler nicht nur zufällig, sondern > garantiert (jedenfalls dann wenn man nicht noch andere Compiler- und > Plattformabhängigkeiten reinbaut ;-). > > Der Blick in Headerdateien ist meist der Anfang eines Fehlers. Der Header stdint.h ist Bestandteil des C-Standards, und er ist genau dazu da, eben keine Compiler- und Plattformabhängigkeiten zu bekommen, wie es z.B. bei explizitem "signed/unsigned char" sein könnte (denn der Standard schreib keineswegs vor, wie groß ein char genau zu sein hat).
Bernd O. schrieb:
> Der Blick in Headerdateien ist meist der Anfang eines Fehlers.
Hast du stdint.h mit limits.h verwechselt?
Bernd O. schrieb: >> Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. > Absolut falsch. > > Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann > schaut man nicht in Header wie <stdint.h>, sondern verwendet die > explizite Form "unsigned char" bzw. "signed char", dann läuft das > Programm auch mit einem anderen Compiler nicht nur zufällig, sondern > garantiert. Na wenn du meinst. Welchen Wertebereich hat denn deiner Meinung nach ein 'unsigned char' oder ein 'signed char'?
Mal andersrum gefragt: Was spricht gegen unsigend char, signed char? Welche Vorteile bietet denn uint8_t und int8_t?
Rufus t. Firefly schrieb: >>> Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. >> Absolut falsch. > > Wieso? Wenn ein Programmieranfänger wissen möchte, wie groß char ist und ob char signed oder unsigned ist, dann läuft er Gefahr, anzunehmen, dass "char" unsigned ist und 8 bits hat. Es ist leider so, dass sehr viele Programmierer glauben, dass char immer 8 bit unsigned ist. Der Ursprung dieses Irrglaubens ist ziemlich klar: Entweder mal in den Headern nachgesehen oder empirisch ermittelt und als "gegeben" abgespeichert. Darum: Gerade als Anfänger nicht in Headern rumsuchen, sondern entweder im ANSI-C-Standard oder in den diversen C-Büchern/Tutorials nachschlagen. Mein "absolut falsch" ist auf Anfänger bezogen. Natürlich spricht nichts dagegen, aus Neugier auch mal in den Headern zu stöbern - aber gerade Anfänger lernen viele falsche Dinge aus dem Studium von Headern. Beispielsweise, dass Präprozessorvariablen mit zwei Unterstrichen beginnen sollen. Das geht eine ganze Weile lang gut und irgendwann hat man ein unerklärliches Programmverhalten, weil sich eine lokaler Bezeichner, der mit zwei Unterstrichen beginnt mit einem Bezeichner aus einer Library deckt. Dito beim Schutz vor Mehrfachincludes durch "__MEINHEADER_H" findet sich leider oft - und wenn der Name des Headers generisch genug ist, dann beißt er sich mit dem System und die Fehlersuche geht los. >> Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann >> schaut man nicht in Header wie <stdint.h>, sondern verwendet die >> explizite Form "unsigned char" bzw. "signed char", > > Was widerspricht Deiner Ansicht nach gegen uint8_t bzw. int8_t ? Kommt darauf an, was man damit vor hat. Um im Embedded-Bereich Arithmetik zu betreiben sind diese Typen gut geeignet. Wenn man aber intensiv mit der C standard library arbeitet sieht es wieder anders aus - oder wie ist der format-string zur ausgabe von uint8_t via printf() - also das Pendant zu "%d für int"? Gruß, Bernd
Sven P. schrieb: > Bernd O. schrieb: >>> Drum sollte man sich i.d.R. auch mal <stdint.h> anschauen. >> Absolut falsch. >> >> Wenn man char für etwas anderes als ASCII-Zeichen nutzen will, dann >> schaut man nicht in Header wie <stdint.h>, sondern verwendet die >> explizite Form "unsigned char" bzw. "signed char", dann läuft das >> Programm auch mit einem anderen Compiler nicht nur zufällig, sondern >> garantiert. > > Na wenn du meinst. Welchen Wertebereich hat denn deiner Meinung nach ein > 'unsigned char' oder ein 'signed char'? Mindestens 0 bis 255 bzw. mindestens -128 bis 127. Je nach Architektur auch mal mehr. Gruß, Bernd
Bernd O. schrieb: > - oder wie ist der format-string zur ausgabe von uint8_t via printf() - > also das Pendant zu "%d für int"? Der ist wasserdicht definiert. Wenn du jedoch nach dem Formatstring zu int32_t gefragt hättest...
Bernd O. schrieb:
> Mindestens 0 bis 255 bzw. mindestens -128 bis 127.
Korrektur:
-127 bit 127 für signed. Liegt an der unterschiedlichen Darstellung
negativer Zahlen (explizites Bit für Vorzeichen vs. Zweierkomplement).
Gruß,
Bbernd
>> Was widerspricht Deiner Ansicht nach gegen uint8_t bzw. int8_t ? > > Kommt darauf an, was man damit vor hat. Um im Embedded-Bereich > Arithmetik zu betreiben sind diese Typen gut geeignet. Wenn man aber > intensiv mit der C standard library arbeitet sieht es wieder anders aus > - oder wie ist der format-string zur ausgabe von uint8_t via printf() - > also das Pendant zu "%d für int"? Dafür sind Macros in /inttypes.h/ definiert. http://www.opengroup.org/onlinepubs/000095399/basedefs/inttypes.h.html
Bernd O. schrieb: > Bernd O. schrieb: > >> Mindestens 0 bis 255 bzw. mindestens -128 bis 127. > Korrektur: > -127 bit 127 für signed. Liegt an der unterschiedlichen Darstellung > negativer Zahlen (explizites Bit für Vorzeichen vs. Zweierkomplement). Na dann... Steht m.W.n. nirgendwo, dass ein char mindestens acht Bit haben muss. Er muss als unsigned lediglich den Basiszeichensatz aufnehmen können, dafür reichen z.B. auch 7 Bit. Mit 'in den Header gucken' meinte ich auch eigentlich weniger, sich die Headerdatei reinzuziehen, sondern eher, mal in der Bibliothek nachzuschauen, was der Header so bietet. Ansonsten ist auch der Formatstring für uint8_t wasserdicht definiert: [c] #include <stdint.h> #include <inttypes.h> printf("%" PRIu8, (uint8_t) 12); [/pre]
> [c] > : > [/pre] Das hat jetzt aber schnell gehen müssen, nicht wahr ;-)
Hoppla ;-) Nönö, hat alle Zeit der Welt, muss eh warten, sons wär ich nich hier. Ich wünschte, es gäbe mal einen 'Test-Übersetzer', der sich zwar 100% an den C-Standard hält, aber alles verquer hat: - char mit 7 oder 9 Bit oder sowas - Zeiger, die im Speicher als wirre Struktur liegen (und deshalb beim Casten nach Integer nicht mehr lineare Adressen ergeben) - ...
wenn man rechnet, sollte man die typen uint8/16/32 benutzen. wenn man strings will sollte man char* benutzen. Warum? weil je nach system die Breite eines Zeichen unterschiedlich sien könnte. "hallo" ist dann zb pointer auf ein array von 16bit werten. wenn dann char* text = "Hallo" steht gehts. steht dann uint8* text= "Hallo" gehts nimmer. gleiches gilt für die signedness von chars, wenn man wirklich zeichenketten will, einfach nur char, da ist das vorzeichen egal. will man rechnen, dann nimmt man sowiso die stdint.h - typen
Sven P. schrieb: > Hoppla ;-) > Nönö, hat alle Zeit der Welt, muss eh warten, sons wär ich nich hier. > > Ich wünschte, es gäbe mal einen 'Test-Übersetzer', der sich zwar 100% an > den C-Standard hält, aber alles verquer hat: > - char mit 7 oder 9 Bit oder sowas > - Zeiger, die im Speicher als wirre Struktur liegen (und deshalb beim > Casten nach Integer nicht mehr lineare Adressen ergeben) Überhaupt: Pointertypen, die je nachdem worauf sie zeigen, unterschiedliche Länge haben.
@Stefan Ernst: > Der Header stdint.h ist Bestandteil des C-Standards, Ja, aber erst seit 10 Jahren. Leider gibt es immer noch Compilerbauer, die es nicht mal gepackt haben, in dieser Zeit den Header mit aufzunehmen. Übrigens muß ein Compiler den eigentlich haben, wenn er von sich behauptete "ANSI"- oder "ISO"-C-konform zu sein, da es das vorher gültige C89 bzw. C90 nicht mehr gibt. Es wurde durch C99 ersetzt. @Sven P.: > Na dann... Steht m.W.n. nirgendwo, dass ein char mindestens acht Bit > haben muss. Das steht in ISO9899 tatsächlich nicht explizit drin. Was aber drin steht, sind die Minimalbereiche von -127 bis +127 bzw. 0 bis 255. Daraus ergibt sich dann implizit eine Größe von mindestens 8 Bit. > Er muss als unsigned lediglich den Basiszeichensatz aufnehmen können, > dafür reichen z.B. auch 7 Bit. Das ist falsch.
1 | #include <stdint.h> |
2 | #include <inttypes.h> |
3 | |
4 | printf("%" PRIu8, (uint8_t) 12); |
Der Cast wird dabei eigentlich nicht benötigt, da der Wert vor der Übergabe sowieso wieder nach int zurückkonvertiert wird. Das bedeutet auch, daß du für uint8_t gefahrlos %d nehmen kannst. > Ich wünschte, es gäbe mal einen 'Test-Übersetzer', der sich zwar 100% > an den C-Standard hält, aber alles verquer hat: Dann brauchst du eine Deathstation 9000: http://dspace.dial.pipex.com/town/green/gfd34/art/ > - Zeiger, die im Speicher als wirre Struktur liegen (und deshalb beim > Casten nach Integer nicht mehr lineare Adressen ergeben) Wie z.B. bei einem PC mit DOS?
> wenn man rechnet, sollte man die typen uint8/16/32 benutzen. Nein. Wenn man Typen braucht, die exakt eine bestimmte Größe haben müssen und weder kleiner noch größer sein dürfen, dann nimmt man diese Typen. Für die Code, wo man nur mindest-Anforderungen an die Größe hat, empfielt sich int_fast8_t bzw. int_least8_t u.s.w., da es je nach Prozessor z.B. nicht unbedingt einen exakt auf die gewünschte Breite passenden Typ geben muß oder dieser eigentlich nicht der optimale ist. > wenn man strings will sollte man char* benutzen. Ja. > "hallo" ist dann zb pointer auf ein array von 16bit werten. > > wenn dann char* text = "Hallo" steht gehts. > steht dann uint8* text= "Hallo" gehts nimmer. Das stimmt, aber vermutlich aus einen anderen Grund, als du denkst. Denn wenn char 16 Bit breit ist, gibt es keinen uint8_t, da char per Definition immer der kleinste Typ ist.
Ich schrieb ja 'm.W.n.', hab mein Wissen aber nachgebessert :-) In C99 steht tatsächlich explizit drin, dass ein char mindestens 8 Bit hat: - Ein 'Objekt' sei in diesem Fall eine Variable eines Types. - Das kleinste Objekt ist eine Variable des kleinsten Types der Sprache (kein Bitvektor). - Das kleinste Objekt soll 8 Bit oder größer sein. (Seite 21, §5.2.4.2.1)
Ich kann euch aus eigener Erfahrung sagen, dass dieses Thema nicht totzukriegen ist. Selbst in der FH kriegen wir beigebracht, dass wir "char" benutzen sollen für 8 bit daten (zum beispiel port bitmasken). Und sowas von einem Professor... In der Schule war es damals auch schon so. Warum kennt niemand stdint.h? Warum legt eigentlich keine Lehrkraft mal Wert auf Ordentlichkeit und Sauberkeit und semantische Korrektheit auch bzgl. der Variablentypen? Das ist der (bzw. ein) Schlüssel zum Erfolg beim Programmieren, möchte ich behaupten...
das problem ist, dass der c99 standard nicht von allen compilern vollständig unterstützt wird (ist ja erst 10 Jahre alt ;). VS 8 hat zB den header auch nicht. >Für die Code, wo man nur mindest-Anforderungen an die Größe hat, >empfielt sich int_fast8_t bzw. int_least8_t u.s.w., da es je nach >Prozessor z.B. nicht unbedingt einen exakt auf die gewünschte Breite >passenden Typ geben muß oder dieser eigentlich nicht der optimale ist. Guter Tip danke, kannte ich auch noch nicht. Das heißt auf einem 32bit DSP bekomme ich dann mit hoher wahrscheinlichkeit für int_fast8_t ein int32.
> Das heißt auf einem 32bit DSP bekomme ich dann mit hoher > wahrscheinlichkeit für int_fast8_t ein int32. Wenn das in diesem Fall schneller ist und der Compiler sinnvoll implementiert ist, ja.
du meinst, wenn die standard-C-header sinnvoll implmementiert sind die int_fastx_t - Typen sind schließlich auch nix anderes als typedefs
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.