Hallo zusammen, als C-Anfänger habe ich folgende, für die meisten von euch wahrscheinlich ziemlich leicht zu beantwortende Fragen: 1. Wie kann ich einzelne Bits eines Zeichens abfragen? Es geht um eine Manchestercodierung, bei der ich ein Daten-Byte habe, das dann in zwei Manchester codierte Bytes umgewandelt wird. Hierfür müsste ich die einzelnen Bits des Datenbytes auslesen. 2. Was mache ich falsch, wenn ich Binärzahlen in C verwenden will, beispielsweise 0b1000000 eingebe und mir der Compiler dann sagt, dass b10000000 eine ungültige Nachsilbe sei? Gruß Christoph
0bx gehört leider nicht zum C-Sprachumfang. Da es aber manchmal sehr nützlich ist, unterstützen es einige Compiler. Zur Abfrage einzelner Bits: dafür gibts mehrere Möglichkeiten. Hier mal eine: if (temp&0x80) // testet Bitstelle 7
@Christoph Budelmann Manche Compiler für uController kennen auch einen Datentyp "bit" damit vielleicht ein union { bit bD0; bit bD1; ... } BitFeld; @crazy horse Ist vielleicht besser so zu schreiben: if (0x00 != (temp & 0x80)) { } da 1. manche Compiler dann gleich einen jnbz / jbz erzeugen 2. manche (uralte) Compiler mit dem "BOOL"-Wert 0x80 nix anfangen können 3. Der Kollege gerade anfängt und deswegen vielleicht diese Verkürzung noch nicht kennt. 4. Ich habe mir es angewöhnt den Konstanten Teil links zu schreiben da dadurch der Fehler "if (i=0) " (Zuweisung anstatt Abfrage) nicht passieren kann (der Compiler sieht das dann als Fehler an) 5. Leerzeichen erhöhen die Üersichtlichkeit, auch wenn es Tipparbeit ist Bitte NICHT bös nehmen Gruss T.Stütz
aus if (test&0x80)... macht mein Compiler: sbrs r16,7 rjmp bit_7_ist_0 .. erkennt also, dass das eine reine Bitabfrage ist. Und zur Schreibweise - da gibt es sehr viele persönliche Vorlieben, jeder muss sehen, wie er am besten zurecht kommt.
@T.Stütz: Zu 1.: aus if(test&0x80) sollte jeder halbwegs gescheite Compiler, der aus dem Alpha-Stadium heraus ist, exakt denselben Code erzeugen wie aus if(0 != (test&0x80)). Zu 2.: Ist dir so ein Compiler schon mal untergekommen? Wenn ja, welcher? Zu 3.: Man sollte diese "Verkürzung" IMHO dann kennen, wenn man das if-Statement lernt. Z.B. einen Test auf Nullpointer wird ja wohl niemand, der seit mehr als ein paar Wochen C lernt, als if(p != 0) schreiben. Man will schließlich testen, ob der Pointer gültig ist, daher ist if(p) sogar semantisch viel einfacher zu verstehen. Zu 4.: Nahezu jeder Compiler erzeugt bei if(i = 0) eine Warnung. Es sei denn natürlich, man hat Warnungen abgeschaltet. Zu 5.: Dem stimme ich zu. Allerdings besteht if(0x0 != (test & 0x80)) aus mehr als ein paar zusätzlichen Leerzeichen. Das 0x0 != sowie die Klammern um den zweiten Term kann man getrost weglassen, ohne die Übersicht zu verschlechtern. Sie wird sogar eher besser. Ich nehm deine Aussagen nicht böse, nur solche Thesen sollten hier nicht einfach so unkommentiert stehenbleiben.
@Chris, NULL muß nach C Standard nicht zwingend 0 sein, ist es aber meistens. Ich hatte z.B. beim 8051 eine Routine, die nicht funktionierte, weil dort 0 eine gültige Datenadresse ist und der Linker die Variable auch dort abgelegt hatte. Da ich nun nicht den gesamten Quelltext (~50 Files) nach if(p) absuchen wollte, habe ich als Workaround dem Linker gesagt, das der XDATA Bereich bei 0x0001 anfängt und dann ging es. Die Schreibweise if(p != NULL) sollte man daher vorziehen. Peter
> NULL muß nach C Standard nicht zwingend 0 sein, ist es aber meistens.
Das ist mir durchaus bekannt.
In diesem Zusammenhang ("if(p != 0)") spielt das allerdings nur eine
untergeordnete Rolle. 0 wird hier automatisch in den Null-Zeiger
konvertiert, egal ob er nun den Zahlenwert 0, 0xFF oder irgendwas
anderes aufweist. Entsprechendes gilt auch für if(p), das ja genau das
gleiche wie if(p != 0) darstellt.
Wenn ein Compiler diese Umwandlung (0 nach Null-Zeiger) nicht
automatisch erledigt, verletzt er AFAIK den ANSI-Standard.
@crazy horse Stimme ich zu @Chris zu1.) Deswegen habe ich auch "(uralt)" geschrieben zu2.) PDOS, der Compiler hat sogar einen normalen Brief zu einer EXE gemacht. Ausserdem Force Unix System V (das ist aber schon 15 Jahre her) zu3.) mit "if (p != 0)" vergleichst du einen konstanten Wert (int) mit einem Zeiger, da muss eigentlich der Compiler eine Warning ausspucken? zu4.) Ja, eine Warnung wird (bei höchstem Warninglevel) ausgespuckt. jedoch wird selbige gerne übersehen oder gemeinhin einfach ignoriert zu5.) "if (0 != temp & 0x80)" => zuerst wird 0 != temp berechnet danach das Ergebnis mit 80h verundet. Siehe auch K&R - C und stimmt es sind ein paar Zeichen mehr und stimmt ich hab da vielleicht etwas "überreagiert" und sorry falls ich jetzt wieder jemand auf den Schlips getreten bin. Grüße @all
> zu2.) PDOS, der Compiler hat sogar einen normalen Brief zu einer EXE > gemacht. Ausserdem Force Unix System V (das ist aber schon 15 Jahre > her) Interesant. Ein if(0x80) hat bei diesen Compilern also zu fehlerhaftem Verhalten geführt? Leider (zum Glück?) bin ich so einen Compiler noch nicht begegnet. Achso, du schreibst ja selbst, dass es schon anderthalb Jahrzehnte her ist. Heutige Compiler können das glücklicherweise durchweg (in dem Fall muss man sich IMHO von Altlasten lösen). > zu3.) mit "if (p != 0)" vergleichst du einen konstanten Wert (int) > mit einem Zeiger, da muss eigentlich der Compiler eine Warning > ausspucken? Siehe mein letztes Posting. In diesem Kontext wird 0 von einem ANSI-C-Compiler implizit in den Nullzeiger konvertiert. > zu4.) Ja, eine Warnung wird (bei höchstem Warninglevel) ausgespuckt. > jedoch wird selbige gerne übersehen oder gemeinhin einfach ignoriert Warnungen sollte man IMHO niemals ignorieren, denn sie weisen auf mögliche logische Fehler hin. Wenn sie aus bestimmten Gründen nicht zu vermeiden sind (z.B. aufgrund einer Compilereigenheit), kann man sie mit #pragma o.ä. selektiv deaktiveren oder den Ausdruck entsprechend umschreiben. > "if (0 != temp & 0x80)" => zuerst wird 0 != temp berechnet > danach das Ergebnis mit 80h verundet. Siehe auch K&R - C Ich meinte "sowie". Nur die Klammern weglassen kann man nicht, das 0x0 != muss dann ebenfalls weg.
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.