PROZESSOR = 18F87K90 Microchip C18 Compiler. char i_help; union reg { char data; struct { char ek : 2; //Elektrodenkontrolle char sprache : 1; //Sprachauswahl char TK : 1; char Temp_Sens : 1; char rx_enable : 1; char RT2025 : 1; char calfail : 1; }; }; union reg reg0; reg0.ek = 0x00; // Geht reg0.ek = 0x01; // Geht reg0.ek = 0x02; // Geht nicht richtig reg0.ek = 0x03; // Geht nicht richtig switch (reg0.ek) { case 0x00 : Do1; // Geht break; case 0x01 : Do2; // Get break; case 0x02 : Do3; // Get nicht break; case 0x03 : Do4; // Get nicht break; default : DoMist; // Hier lande ich bei 0x02 und 0x03 break; } So nun hab ich folgendes kleines Problem. Wieso geht das nicht ?? reg0.ek ist ja 2 Bit breit, womit es insgesammt 4 zustände annehmen kann. Ich kenn jedoch nur die zustände 0x00 und 0x01 auswerten, 0x02 und 0x03 bekomme ich nie ausgewertet. Wenn ich reg0.ek einen anderen wert als 0x00 oder 0x01 zuweise, lnde ich immer in DoMist. Habe ich irgendwo einen Denkfehler? Der Debugger meldet mir in reg0.ek immer den richtigen wert.
versuch mal
1 | ...
|
2 | unsigned char ek : 2; //Elektrodenkontrolle |
3 | ...
|
natürlich bei allen variablen. Volker
Charakter mit Vorzeichen habe ich sowieso noch nie gesehen ...
duck&wech schrieb: > Charakter mit Vorzeichen habe ich sowieso noch nie gesehen ... Es kommt immer darauf an wie das der Compiler sieht. Ich hatte mal das Problem das ein Microsoft Visual C++ Programm immer dann gecrasht ist, wenn aus einer Datei ein ß gelesen und an isdigit gefüttert wurde. char c = '▀'; // 0xDF isdigit(c); // crash Ursache: Übergabeparameter wird von signed char auf int erweitert. Workaround: isdigit((unsigned char)c);
Cool hatte nun geklappt. Also macht der Compiler oder wer auch immerein 0x00, 0x01 und ein 0xFF und 0xFE draus. Danke nochmal.
Ich hatte auch bisher immer gedacht das ein Char kein vorzeichen hatt. bei C18 ist das aber anscheinend anders. http://www.sprut.de/electronic/pic/c/pic_c/pic_c20_variablen.html Der post oben drüber bezieht sich darauf, dass ich i_help den wert von reg0.ek zuweise. Danach dürfte i 0x00, 0x01, xFF oder 0xFE haben.
Jdelphi schrieb: > Der post oben drüber bezieht sich darauf, dass ich i_help den wert von > reg0.ek zuweise. Danach dürfte i 0x00, 0x01, xFF oder 0xFE haben. Besser (anschaulicher) : -2,-1,0 und 1.
Jdelphi schrieb: > Ich hatte auch bisher immer gedacht das ein Char kein vorzeichen hatt. Das ist in C nicht festgelegt und wird der jeweiligen Implementierung überlassen. Darum ist es zb extrem wichtig, dass man sich die Sichtweisen aneignet: char für Textverarbeitung signed char für alle Berechnungen mit kleinen Zahlen mit Vorzeichen unsigned char für alle Berechnungen mit kleinen Zahlen ohne Vorzeichen Am besten fährt man, wenn man es sich zur Gewohnheit macht, zwischen diesen 3(!) Datentypen streng zu unterscheiden. char ist ausschliesslich für Zeichenverarbeitung reserviert und wenn man mit Bytes operiert, dann ist unsigned char der richtige Datentyp. Alles andere führt über kurz oder lang immer irgendwann zu Problemen. Und sei es nur bei automatischen Datetyperweiterungen (Integer Promotions), wenn ein char laut Standard-C-Regeln zu einem int aufgeblasen werden muss.
Karl Heinz Buchegger schrieb: > Am besten fährt man, wenn man es sich zur Gewohnheit macht, zwischen > diesen 3(!) Datentypen streng zu unterscheiden. Blöd ist nur, wenn man Protokolle hat, die Text und Daten enthalten (was in der Regel der Fall ist). Bei unsigned char meckert der GCC, wenn man es als Text parst. Bei char wird nicht gemeckert, aber dann geht das Daten auslesen schief, da char nach signed int expandiert. Wie kann man nur auf die blöde Idee kommen, daß es negativen Text gibt. Die C-Entwickler haben einem damit ein ganz schönes Ei ins Nest gelegt, das jeder Programmierer ausbaden muß und sich dumm und dämlich castet. Ich bin darauf auch schon reingefallen. Am saubersten wäre es, Datenströme immer als unsigned zu definieren und dem GCC das Meckern darüber abschalten zu können. Peter
Peter Dannegger schrieb: > Wie kann man nur auf die blöde Idee kommen, daß es negativen Text gibt. Anno 1970 gab es nur positiven Text, weil der ASCII-Zeichensatz nur die Werte 0-127 kennt. Umlaute hatten die Amerikaner nicht auf der Rechnung. > Die C-Entwickler haben einem damit ein ganz schönes Ei ins Nest gelegt Genau genommen waren es nicht die C-Entwickler, sondern DEC. Damals brachte DEC die PDP-11 raus, deren Bytebefehle die Daten vor der Rechnung vorzeichenbehaftet nach 16 Bits konvertiert und dann verarbeitet. Wem da ein gewisser Zusammenhang mit der Definition von C auffällt: Auf solchen Maschinen hat Unix seine Kindheit verbracht, und damit auch C. Vorzeichenlos wäre Zeichenverarbeitung weniger effizient gewesen. Und weil viele sich daran gewöhnt hatten, dass "char" vorzeichenbehaftet ist, hat man das so fortgesetzt und viele Compiler machen das auch heute noch so. Nicht selten umschaltbar.
A. K. schrieb: >> Die C-Entwickler haben einem damit ein ganz schönes Ei ins Nest gelegt > > Genau genommen waren es nicht die C-Entwickler, sondern DEC. > > Damals brachte DEC die PDP-11 raus, deren Bytebefehle die Daten vor der > Rechnung vorzeichenbehaftet nach 16 Bits konvertiert und dann > verarbeitet. Wem da ein gewisser Zusammenhang mit der Definition von C > auffällt: Auf solchen Maschinen hat Unix seine Kindheit verbracht, und > damit auch C. Vorzeichenlos wäre Zeichenverarbeitung weniger effizient > gewesen. Interessante Anekdote. Das wusste ich bisher gar nicht. Dank dafür. Aber Peter hat schon recht. Da ist wohl jeder im Laufe seiner Laufbahn ein paar mal reingefallen. Und aus Erfahrung weiß ich: Bei sowas suchst du dich dumm und dämlich. if( c == 212 ) der Debugger zeigt dir c in hex an, 0xD4 ist 212, und du denkst die ganze Zeit: verdammt, das Bitmuster stimmt. Warum schlägt der Vergleich nicht an!
Wie wird das denn bei IBM mit EBCDIC gelöst? Oder nimmt man da nur Fortran oder Cobol :-)
DirkB schrieb: > Wie wird das denn bei IBM mit EBCDIC gelöst? Bloss weil DEC bei der PDP-11 die Byteverarbeitung so implementierte, dass man Reste davon noch heute in C wiederfindet, musste IBM das Jahre zuvor ja nicht auch so machen. Und ja, die IBMs 360/370er wurden nicht mit C behelligt, sondern hauptsächlich mit Fortran, Cobol und viel Assembler. Oder PL/I. Die Besonderheit an C ist die Einstufung von Einzelzeichen als Zahlenwerte, also "char" als kleiner Integer. Das ist in anderen Sprachen ungebräuchlich. Ohne dies hat man das Problem nicht.
Peter Dannegger schrieb: > Blöd ist nur, wenn man Protokolle hat, die Text und Daten enthalten (was > in der Regel der Fall ist). Dafür haben die C-Götter den typecast erfunden. Den muss man bei Texten dann typischerweise zweimal benutzen: jeweils an der Import- und an der Export-Schnittstelle, also bspw.
1 | char buf[]; |
2 | |
3 | buf[idx++] = (char)UDR; |
4 | |
5 | ...
|
6 | |
7 | lcd_sendbyte((uint8_t)*cp++); |
marcus6100 schrieb: > Ich hatte mal das Problem das ein Microsoft Visual C++ > Programm immer dann gecrasht ist, wenn aus einer Datei > ein ß gelesen und an isdigit gefüttert wurde. > > > char c = '▀'; // 0xDF > isdigit(c); // crash > > Ursache: Übergabeparameter wird von signed char auf int erweitert. > > Workaround: > isdigit((unsigned char)c); Das ist kein Workarund, sondern der von C so vorgesehene Weg, auch wenn das wirklich blöd ist. Die ISO-Norm sagt zu allen Funktionen, die mit einzelnen Zeichen arbeiten: ************************************************************************ ****** The header <ctype.h> declares several functions useful for classifying and mapping characters. In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined. ************************************************************************ ****** Das Verhalten des Compilers ist also korrekt. Jdelphi schrieb: > Ich hatte auch bisher immer gedacht das ein Char kein vorzeichen hatt. > bei C18 ist das aber anscheinend anders. Eigentlich haben sie meistens eins. ISO C läßt dem Compiler hier die Wahl, aber mit Vorzeichen ist eigentlich sinnvoller, da ja auch alle anderen Integer-Typen ein Vorzeichen haben, wenn weder signed noch unsigned davorsteht. Peter Dannegger schrieb: > Wie kann man nur auf die blöde Idee kommen, daß es negativen Text gibt. Aber positiven? Es gibt bei Text schlicht und ergreifend kein Konzept "vorzeichenlos oder vorzeichenbehaftet". Es ist einfach Text, und da man mit Text nicht rechnet, ist die "Vorzeichenbehaftetheit" des dahinterstehenden Datentyps egal. > Die C-Entwickler haben einem damit ein ganz schönes Ei ins Nest gelegt, > das jeder Programmierer ausbaden muß und sich dumm und dämlich castet. Das ist aber doch in den meisten Sprachen so. In vielen anderen Sprachen kann man mit dem Zeichentyp halt nur nicht direkt rechnen, aber wenn ich rohe Bytes habe, muß ich die eigentlich in so gut wie jeder Sprache erstmal konvertieren, um sie als Text nutzen zu können. Das mußt du in C halt auch...
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.