Niklas M. schrieb:> bekomme jedoch nicht den richtigen Wert.
Was ist denn der "richtige" Wert? Was erwartest du als Ausgabe?
char ist ist vorzeichenloser Wert.
-16 enspricht binär 1111 0000. Als vorzeichenlose Zahl ist das 240.
Siehe Zeile 9. Addierst du 20, rechnet er 240+15=255, läuft mit +1 über
zu 0 und es bleiben noch 4 übrig. Siehe Zeile 11.
Mit int passiert das ganze im Prinzip genauso, nur wird das MSB als
Vorzeichen gedeutet.
Es passiert alles genauso, wie es C soll.
Deswegen:
> Was mache ich falsch?
Du versuchst etwas, dass so keinen Sinn ergibt. Was soll ein negativer
char sein? Was versuchst du zu erreichen?
MKr:
>Was ist denn der "richtige" Wert? Was erwartest du als Ausgabe?>char ist ist vorzeichenloser Wert.
Nicht zwingend:
https://de.wikipedia.org/wiki/Datentypen_in_C#Character
"Ein Character repräsentiert die kleinste adressierbare Einheit in C, in
der Regel acht Bit. Deshalb wird die Größe von Objekten und Typen oft
als ganzzahliges Vielfaches eines Characters angegeben. Je nach Compiler
kann char entweder gleichbedeutend sein mit signed char (meistens -128
bis 127) oder mit unsigned char (meistens 0 bis 255)."
OK, das mag sein, wenn ich persönlich auch den Sinn des ganzen nicht
sehe. Will ich eine Ganzzahl darstellen? -> int in irgendeiner
Ausprägung.
Ein Zeichen? -> Char. Dann folgt es der ASCII-Tabelle und die geht nur
für 7 Bit, das 8. ist "ü"
Geht es mir, z.B. für die Übertragung, nur um die reine Bitfolge und
soll das ganze für die verschiedensten Datentypen kompatibel sein, kann
man das mit char machen. Wobei alle dann nur die reine Bitfolge
interessiert und deren Deutung an der Stelle irrelevant ist. Damit auch
Vorzeichen oder eben nicht.
Aber das ist meine persönliche Meinung, die nicht zur Diskussion steht
und soll nicht Thema dieses Threads sein und hilft dem OT nicht.
Ergo:
MKr schrieb:> Was versuchst du zu erreichen?
Er wusste nur nicht, dass char von Compiler mit oder ohne Vorzeichen
behandelt werden. Das hängt von dem default des Compiler ab oder von der
Option, die dem Compiler sagt, wie er char behandeln soll.
Ich denke der Test war nur zum Verständnis und ist dafür gut geeignet.
MKr schrieb:> Was erwartest du als Ausgabe?
Ich hatte -16 erwartet.
In Konsolenanwendungen mit printf hat das bis jetzt auch immer
funktioniert. Also z.B. so:
1
charcTest=-16;
2
printf("%d",cTest);
MKr schrieb:> char ist ist vorzeichenloser Wert.
Ich denke hier liegt mein Fehler. Ich dachte char sei das Gegenstück zu
unsigned char mit einem Wertebereich von –128 bis +127.
MKr schrieb:> Will ich eine Ganzzahl darstellen? -> int in irgendeiner> Ausprägung.> Ein Zeichen? -> Char.
Danke, das wäre meine nächste Frage gewesen. Ich habe bis jetzt char
immer für beides benutzt und das Formatierungszeichen im printf
entsprechend angepasst.
MKr schrieb:> Was versuchst du zu erreichen?
Ich habe keine Aufgabe oder so, versuche Programmieren zu lernen.
Niklas M. schrieb:> Ich habe keine Aufgabe oder so, versuche Programmieren zu lernen.
Sehr löblich und viel Erfolg dabei!
Niklas M. schrieb:> Ich dachte char sei das Gegenstück zu> unsigned char mit einem Wertebereich von –128 bis +127.
Mir ist bis jetzt noch kein Fall untergekommen, in dem signed char
verwendet wurde oder sinnvoll gewesen wäre. Zugegeben, muss das nichts
heißen. Mir fällt aber auch kein Fall ein. Es muss welche geben, sonst
gäbe es das Konstrukt nicht.
Niklas M. schrieb:> printf("%d", cTest);
An dieser Stelle hast du dem Compiler gesagt, dass er deine Bitfolge als
int interpretieren soll und damit wurde es eine vorzeichenbehaftete
Ganzzahl. Es war kein char mehr. Das erklärt deine Verwirrung
Niklas M. schrieb:> Ich habe bis jetzt char> immer für beides benutzt und das Formatierungszeichen im printf> entsprechend angepasst.
Gewöhne dir an, für deine Daten den passenden Datentyp zu verwenden. Das
macht zum einen deine Programme verständlicher und übersichtlicher und
zum anderen kann dir der Compiler dann helfen, Fehler zu vermeiden, wenn
du Typecasts machst. Zumindestens kann er dir dann Hinweise geben.
Übersichtlicher z.B. wegen:
1
chara='a';
2
charb='b';
3
charc=a+b;
Der Compiler macht das ohne Probleme. Aber welchen Sinn hat es (an
dieser Stelle), Buchstaben zu addieren?
MKr schrieb:> Gewöhne dir an, für deine Daten den passenden Datentyp zu verwenden.
Genau dafür hasse ich C++, diese scheiß Deklaration der Datentypen hat
mich schon Stunden beschäftigt.
MKr schrieb:
> Gewöhne dir an, für deine Daten den passenden Datentyp zu verwenden.
+1
Und lerne die verschiedenen Datentpen und deren Anwendung zuerst!
Manfred schrieb:> Genau dafür hasse ich C++, diese scheiß Deklaration der Datentypen hat> mich schon Stunden beschäftigt.
Darin unterscheiden sich eben diejenigen, die programmieren können. Ohne
Kenntnis der Datentypen wirst Du mit keiner Programmiersprache glücklich
werden.
Niklas M. schrieb:> MKr schrieb:>> char ist ist vorzeichenloser Wert.>> Ich denke hier liegt mein Fehler. Ich dachte char sei das Gegenstück zu> unsigned char mit einem Wertebereich von –128 bis +127.
Das wäre signed char. Prinzipiell ist char einfach nur der kleinste
Integer-Typ. Aber es gibt zu den anderen, also short int, int, long int
und long long int einen Unterschied: Während bei diesen ohne einen
signed/unsigned-Präfix immer ein signed impliziert wird (also signed
short int und short int sind der selbe Typ), ist das bei char nicht so.
Da sind char, signed char und unsigned char drei verschiedene Typen.
char kann dabei je nach Compiler die selbe Darstellung wie signed oder
wie unsigned haben. Der Typ ist eigentlich auch nicht zum Rechnen
gedacht, sondern nur dazu, ein Zeichen zu speichern. Dahrer gilt: Für
Text immer char, wenn man rechnen will dagegen explizit signed oder
unsigned char.
MKr schrieb:> Mir ist bis jetzt noch kein Fall untergekommen, in dem signed char> verwendet wurde oder sinnvoll gewesen wäre. Zugegeben, muss das nichts> heißen. Mir fällt aber auch kein Fall ein. Es muss welche geben, sonst> gäbe es das Konstrukt nicht.
Das kommt vermutlich in der Praxis eher selten vor, vor allem auf
nicht-8-Bit-Plattformen, aber prinzipiell ist es nix anderes als bei den
andern Integer-Typen auch.
> Niklas M. schrieb:>> printf("%d", cTest);> An dieser Stelle hast du dem Compiler gesagt, dass er deine Bitfolge als> int interpretieren soll und damit wurde es eine vorzeichenbehaftete> Ganzzahl. Es war kein char mehr. Das erklärt deine Verwirrung
Das ist aber hier nicht das Problem, denn int ist in der Regel größer
als char und damit auch in der Lage, den ganzen Wertebereich davon
abzudecken, egal ob das nun ein Vorzeichen hat oder nicht. Das Problem
ist eher, dass auf einer der getesteten Plattformen char ein Vorzeichen
hat, auf der anderen aber nicht. Genau deshalb soll man char ohne
(un)signed-Präfix nie zum Rechnen verwenden.
Manfred schrieb:> MKr schrieb:>> Gewöhne dir an, für deine Daten den passenden Datentyp zu verwenden.>> Genau dafür hasse ich C++, diese scheiß Deklaration der Datentypen hat> mich schon Stunden beschäftigt.
Statt die Emotionen ausufern zu lassen, wäre es ggf. sinnvoller,
einmalig etwas Zeit in das Verständnis der Datentypen zu investieren.
Das ist nun auch keine Raketenwissenschaft. Muss man übrigens bei jeder
Sprache.
MKr schrieb:> Übersichtlicher z.B. wegen:char a='a';> char b='b';> char c=a+b;> Der Compiler macht das ohne Probleme. Aber welchen Sinn hat es (an> dieser Stelle), Buchstaben zu addieren?uint8_t a=97;> uint8_t b=98;> uint8_t c=a+b;> ergibt da schon mehr Sinn
char nimmt man, wenn man Zeichen bearbeiten möchte.
ein 'a'+'b' mag wenig sinnvoll erscheinen, ein 'a' + 1 erscheint
sinnvoller und ein 'z'-'a' ist sehr sinnvoll.
Magic Numbers sollte man auch nicht benutzen.
uint8_t ist nur ein typedef für signed char
Das Serial.println erkennt wohl am Typ vom ersten Parameter was es
machen soll und erkennt bei einem int8_t auch nur ein char.
Jonas B. schrieb:>>uint8_t ist nur ein typedef für signed char>> Das "u" vor dem "int" besagt das es unsigned ist.
Danke.
🙄 warum kann man sich nicht an unwichtigeren Stellen verschreiben 🤷♂️
Guten Morgen,
nachdem mir klar wurde um was es geht, habe ich in meinem Lehrbuch das
Kapitel zu Datentypen noch einmal nachgeschlagen und muss gestehen, dass
dort eigentlich die ganze Thematik erklärt wurde.
Asche über mein Haupt, das habe ich damals wohl schlicht überlesen/nicht
verstanden.
Vielen Dank an alle, die sich die Mühe gemacht haben mir weiterzuhelfen
:)
Grüße Niklas
Rolf M. schrieb:> wenn man rechnen will dagegen explizit signed oder> unsigned char.
Das funktioniert, verschleiert aber an der Stelle den Sinn des Codes.
Deswegen würde ich es nicht tun.
Dirk B. schrieb:> uint8_t ist nur ein typedef für signed char
Auch hier würde ich IMMER uint8_t verwenden, weil dadurch impliziert
wird, dass mit Zahlen und nicht mit Zeichen gerechnet wird. Auch, wenn
es im Maschinencode das selbe Ergebnis hat.
Dirk B. schrieb:> char nimmt man, wenn man Zeichen bearbeiten möchte.> ein 'a'+'b' mag wenig sinnvoll erscheinen, ein 'a' + 1 erscheint> sinnvoller und ein 'z'-'a' ist sehr sinnvoll.
Völlig korrekt, es gibt Anwendungen, bei denen mit Zeichen gerechnet
wird. Das wollte ich auch nicht ausschließen. Der OT hat aber keine
Zeichenmanipulation betrieben, sondern wirklich mit Zahlen gerechnet.
Deswegen mein "sinnloses" Bespiel und kein sinnvolles
MKr schrieb:> Rolf M. schrieb:>> wenn man rechnen will dagegen explizit signed oder>> unsigned char.> Das funktioniert, verschleiert aber an der Stelle den Sinn des Codes.
Ich sehe nicht, wie da was verschleiert werden sollte. Wenn da explizit
signed char oder unsigned char steht, heißt das für mich ganz klar, dass
es nicht um Text geht.
> Dirk B. schrieb:>> uint8_t ist nur ein typedef für signed char> Auch hier würde ich IMMER uint8_t verwenden, weil dadurch impliziert> wird, dass mit Zahlen und nicht mit Zeichen gerechnet wird.
Damit wird auch impliziert, dass es zwingend exakt 8 Bit sein müssen.
Wenn mir das an der Stelle egal ist und der Typ einfach nur der
kleinstmögliche sein soll, tut's ein unsigned char auch.
> Dirk B. schrieb:>> char nimmt man, wenn man Zeichen bearbeiten möchte.>> ein 'a'+'b' mag wenig sinnvoll erscheinen, ein 'a' + 1 erscheint>> sinnvoller und ein 'z'-'a' ist sehr sinnvoll.> Völlig korrekt, es gibt Anwendungen, bei denen mit Zeichen gerechnet> wird.
Ich würde soweit gehen, zu sagen, dass das nicht stimmt. Ein 'a' ist
keine Zahl, mit der man rechnen könnte. Natürlich hat es einen
Zeichencode, mit dem man durchaus rechnen könnte, aber das sind für mich
zwei verschiedene Dinge. In C und C++ ist diese Unterscheidung leider
nicht konsequent umgesetzt, aber in anderen Sprachen kann man sie sehr
deutlich erkennen. In Pascal z.B. gibt es auch einen Typ char, aber mit
dem kann man nicht rechnen. Ein 'a' + 5 wird mit Fehler quittiert. Man
kann einen char auch nicht mit einem Zahlenwert initialisieren. Wenn man
damit rechnen will, muss man das Zeichen erst in einen Integer-Wert
konvertieren, dann damit rechnen, und wenn es am Ende wieder ein Zeichen
sein soll, muss man eben wieder nach char zurückwandeln. Ich schlage nun
vor, in C und C++ das selbe zu machen. Der Unterschied ist hier nur,
dass diese Sprachen theoretisch auch ein direktes Rechnen mit dem char
erlauben, aber man sollte dies trotzdem nicht tun.
MKr schrieb:> Auch hier würde ich IMMER uint8_t verwenden, weil dadurch impliziert> wird, dass mit Zahlen und nicht mit Zeichen gerechnet wird.
Dann sollte man aber uint_least8_t nehmen. Denn das funktioniert auch,
wenn char keine 8 Bit hat.
> Mir ist bis jetzt noch kein Fall untergekommen, in dem signed char> verwendet wurde
Die meisten Systeme, insb x86 Linux und Windows, haben signed char als
default. Bei PowerPC, ARM und 8-Bittern findet man eher unsigned char.