www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Binärzahlen und Abfrage einzelner Bits in C /


Autor: Christoph Budelmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: T.Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: T.Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.