Forum: Mikrocontroller und Digitale Elektronik einzene Bits prüfen ( if (bit) {.} )


von Chris (Gast)


Lesenswert?

Hallo zusammen,

in Assembler (pic) gibts "btfss Flag", dadurch kann ich ein einzelnes 
Bit prüfen ob es 0 oder 1 ist.
Gibts es eine Möglichkeit in 'C' das auch zu tun, oder erfolgt die 
Prüfung nur Byteweise?

Gruß

von Jan M. (mueschel)


Lesenswert?

Das übliche Konstrukt lautet (für Bit 6):

if (byte & (1 << 6))
oder
if (byte & 0x40)

In der Regel wird der Compiler das dann auf den entsprechenden 
asm-Befehl zurückführen.

von 2920 (Gast)


Lesenswert?

Das als hardwarenahe bekannte C, hat offensichtlich seit 25 Jahren nie 
die Flexibilitaet gefunden, die Funktion expliit zu ermoeglichen . Man 
erwartet, dass der Compiler schlau genug ist das selbst herauszufinden 
und zu machen

von yalu (Gast)


Lesenswert?

> Das als hardwarenahe bekannte C, ...

Gerade weil C so hardwarenah ist, ist das so.

Bei weitem nicht alle Mikroprozessoren haben Befehle zum Setzen,
Löschen und Abfragen einzelner Bits per Bitnummer. Aber wohl jeder
Prozessor der letzten 40 Jahre hat Befehle für bitweise
Logikverknüpfungen und Schiebeoperationen. Deswegen hat man sich dafür
entschieden, genau diese Befehle in C abzubilden. Und die
Einzelbitbefehle lassen sich ja, wie gezeigt wurde, leicht aus Logik-
und Schiebebefehlen zusammensetzen und, wenn man möchte, in Makros
kapseln.

> ... nie die Flexibilitaet gefunden, ...

Die bitweisen Logikverknüpfungen sind wesentlich flexibler als
Einzelbitbefehle, da man damit auch mehrere Bits gleichzeitig setzen,
löschen oder abfragen kann. Und beliebig viele Operatoren konnten halt
auch nicht implementiert werden, da dabei irgendwann die Sonderzeichen
auf der Tastatur ausgehen ;-)

von Just another Peter (Gast)


Lesenswert?

ich bin ja trotzdem dafür, dass man in C bits rotieren und das 
carry-flag abfragen können sollte :-(

von Jens Plappert (Gast)


Lesenswert?

Tja, am liebsten wäre wohl allen ein Assembler-C-Basic -Hybrid.

Aber wie wärs mit Inline-Assembler?

von Thomas M. (thomas1123) Benutzerseite


Lesenswert?

1
char _var; // die variable in der du ein einzelnes bit abfragen willst
2
3
if ((_var & 0b00001000) >= 1) /* die 1 gibt das bit an welches du abfragen willst.*/
4
{
5
   x=y; // was auch immer dann halt passieren soll
6
}
 dabei handelt es sich um eine UND funktion bei der du schaust ob das 
ergebnis >= 1 ist oder nicht.
du musst nachschauen ob die zahl gleich grösser 1 ist denn wenn du bit 
nummer 2 setzt sind das ja dann 4 und nicht 1

hoffe du kannst damit was anfangen

von Johannes M. (johnny-m)


Lesenswert?

Thomas Müller wrote:
>
1
> char _var; // die variable in der du ein einzelnes bit abfragen willst
2
> 
3
> if ((_var & 0b00001000) >= 1) /* die 1 gibt das bit an welches du
4
> abfragen willst.*/
5
> {
6
>    x=y; // was auch immer dann halt passieren soll
7
> }
8
> 
9
>
>  dabei handelt es sich um eine UND funktion bei der du schaust ob das
> ergebnis >= 1 ist oder nicht.
> du musst nachschauen ob die zahl gleich grösser 1 ist denn wenn du bit
> nummer 2 setzt sind das ja dann 4 und nicht 1
Und jetzt überleg mal, welche Werte das ganze überhaupt annehmen kann... 
Und irgendwann kommst Du vermutlich zu dem Schluss, dass völlig 
unabhängig davon, welches Bit es sein soll, eine Abfrage auf "> 0" 
oder "!= 0" völlig ausreicht. Und in dem Fall kann man den Vergleich 
auch komplett weglassen und einfach schreiben
1
if (var & 0b00001000)
Und den Underscore ("_") vor dem "var" solltest Du tunlichst weglassen. 
Sämtliche Bezeichner, die mit einem oder mehreren Unterstrichen 
beginnen, sind für Compiler und lib reserviert und dürfen vom 
Programmierer nicht vergeben werden.

Außerdem ist die Binärschreibweise mit "0bXXXXXXXX" nicht vom 
ANSI-Standard abgedeckt und dementsprechend wird sie nicht von allen 
Compilern unterstützt! Genau deshalb nimmt man schließlich die 
Bitschiebe-Schreibweise, die ist nämlich zu 100% portierbar, weil 
ANSI...

von Detlef _. (detlef_a)


Lesenswert?

Just another Peter wrote:
> ich bin ja trotzdem dafür, dass man in C bits rotieren und das
> carry-flag abfragen können sollte :-(

Geht doch:
int8_t cc;cc=(cc<<1)|(cc>>7); carryflag =c&1;
Is zwar nicht so elegant, dafür muß man sich die kryptische rot/rol/rofl 
Assembler Syntax der Prozessoren nicht merken.

Cheers
Detlef

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
Noch kein Account? Hier anmelden.