Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 8 Operatoren
  gp 8.1 Exkurs zu Operatoren
  gp 8.2 Arithmetische Operatoren
    gp 8.2.1 Dividieren von Ganzzahlen
  gp 8.3 Erweiterte Darstellung arithmetischer Operatoren
  gp 8.4 Inkrement- und Dekrement-Operatoren
  gp 8.5 Bit-Operatoren
    gp 8.5.1 Bitweises UND
    gp 8.5.2 Bitweises ODER
    gp 8.5.3 Bitweise XOR
    gp 8.5.4 Bitweises Komplement
    gp 8.5.5 Linksverschiebung
    gp 8.5.6 Rechtsverschiebung
    gp 8.5.7 Rezept für Fortgeschrittene
  gp 8.6 sizeof-Operator
    gp 8.6.1 C versus C++


Galileo Computing - Zum Seitenanfang

8.5 Bit-Operatoredowntop

Mit Hilfe von Bit-Operatoren kann direkt auf die binäre Darstellung der Zahlen zurückgegriffen werden.

Zuerst eine kurze Übersicht, welche Bit-Operatoren es gibt:


Tabelle 8.5   Übersicht der bitweisen Operatoren

Bit-Operator Bedeutung
&, &= Bitweise AND-Verknüpfung
|, |= Bitweise OR-Verknüpfung
^, ^= Bitweise XOR
~ Bitweises Komplement
>>, >>= Rechtsverschiebung
<<, <<= Linksverschiebung

Wie schon bei den arithmetischen Operatoren steht Ihnen auch bei den bitweisen Operatoren die erweiterte Zuweisungsschreibweise zur Verfügung.


Hinweis   Es ist nicht zulässig, als Operanden float bzw. double zu verwenden. Die Operanden müssen bei der Verwendung von Bit-Operatoren immer ein ganzzahliger Datentyp sein.



Galileo Computing - Zum Seitenanfang

8.5.1 Bitweises UNdowntop

Steht der &-Operator zwischen zwei Operanden, so handelt es sich um den bitweisen UND-Operator. Dieser ist leicht mit dem unären Adressoperator (siehe scanf()) zu verwechseln.

Der Operator wird hauptsächlich dafür verwendet, einzelne Bits gezielt zu löschen. Folgendes Programmbeispiel soll dies demonstrieren:

/* and.c */
#include <stdio.h>
int main(void) {
   int x=55;
   printf("x=%d\n",x);
   x= x&7;
   printf("x=%d\n",x);  /* x=7 */
   return 0;
}

Nach der Ausführung des Programms werden Sie sich fragen, warum die Verknüpfung mit dem UND-Operator zum Ergebnis 7 führt. Sehen Sie sich dies wieder in der Bitdarstellung an (unter Verwendung der ersten 8 Bits):

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 8.3   Verwendung des bitweisen UND-Operators

Dabei gelten per Definition folgende Regeln für den bitweisen UND-Operator:


Tabelle 8.6   Regeln einer bitweisen UND-Verknüpfung

BitA BitB BitA&BitB
0 0 0
0 1 0
1 0 0
1 1 1

Mit dem bitweisen UND-Operator lässt sich sehr gut testen, ob eine Zahl gerade oder ungerade ist. Es muss nur Bit 0 (bzw. das 1. Bit) daraufhin überprüft werden, ob es gesetzt (ungerade, also = 1) oder nicht gesetzt (gerade, also = 0) ist. Folgendes Beispiel demonstriert dies:

/* gerade.c */
#include <stdio.h>
int main(void) {
   int x;
   printf("Bitte geben Sie eine Zahl ein: ");
   scanf("%d",&x);
   if(x&1)  // Ist das erste Bit gesetzt?
      printf("Eine ungerade Zahl\n");
   else     // Nein, es ist nicht gesetzt
      printf("Eine gerade Zahl\n");
   return 0;
}

Galileo Computing - Zum Seitenanfang

8.5.2 Bitweises ODEdowntop

Mit dem bitweisen ODER-Operator können Sie gezielt zusätzliche Bits setzen. Verwendet wird dieser wie schon zuvor der bitweise UND-Operator:

char x = 1;
x = x|126;    // x=127

Auch hierzu die Bitdarstellung:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 8.4   Verwendung des bitweisen ODER-Operators

Für den ODER-Operator gilt folgende Verknüpfungstabelle:


Tabelle 8.7   Regeln einer bitweisen ODER-Verknüpfung

BitA BitB (BitA|BitB)
0 0 0
0 1 1
1 0 1
1 1 1


Galileo Computing - Zum Seitenanfang

8.5.3 Bitweise XOdowntop

Dieser exklusive ODER-Operator liefert nur dann eine 1 zurück, wenn beide Bits unterschiedlich sind. Er ist sehr gut geeignet, um Bits umzuschalten. Alle gesetzten Bits werden gelöscht und alle gelöschten gesetzt. Beispielsweise:

char x=20;
x = x^55;    // x=35

In binärer Darstellung ergibt sich aus dieser Operation folgendes Bild:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 8.5   Verwendung des exklusiven ODER-Operators

Für XOR-Verknüpfungen gilt folgende Verknüpfungstabelle:


Tabelle 8.8   Regeln einer bitweisen XOR-Verknüpfung

BitA BitB BitA^BitB
0 0 0
0 1 1
1 0 1
1 1 0


Galileo Computing - Zum Seitenanfang

8.5.4 Bitweises Komplemendowntop

Der NOT-Operator (~) wirkt sich auf Zahlen so aus, dass er jedes einzelne Bit invertiert. Bei vorzeichenbehafteten Datentypen entspricht das einer Negation mit anschließender Subtraktion von 1:

char x=20;
x=~x;  /* x= –21 */

Für den NOT-Operator gilt folgende Verknüpfungstabelle:


Tabelle 8.9   Regeln einer bitweisen NOT-Verknüpfung

BitA ~BitA
0 1
1 0


Galileo Computing - Zum Seitenanfang

8.5.5 Linksverschiebundowntop

Mit einer Linksverschiebung (<<) werden alle Bits einer Zahl um n Stellen nach links gerückt. Die rechts entstehenden Leerstellen werden mit 0 aufgefüllt.


Achtung   Achtung bei Vorzeichen! Ist der Datentyp signed, ändert sich das Vorzeichen, wenn eine 1 in die Bitstelle des Vorzeichens gerückt wird. Falls der linke Operand aber einen negativen Wert hat, so ist das Ergebnis Compiler-spezifisch.


Beispiel einer Linksverschiebung:

/* shift_left.c */
#include <stdio.h>
int main(void) {
   char x=8;
   printf("x=%d\n",x);
   x<<=1;        // Alle Bits um 1 Stelle nach links
   printf("x=%d\n",x);
   return 0;
}

Warum aus dem Wert 8 eine 16 wurde, wird aus der folgenden Bitdarstellung ersichtlich:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 8.6   Bitverschiebung nach links

Sie werden es bemerkt haben, hier wurde eine Multiplikation durchgeführt. Auf diese Weise können Zahlen sehr gut potenziert werden. Die Bitstelle um eine Position nach links zu rücken, bedeutet mathematisch eine Multiplikation mit 2. Bei Einrückung um zwei Stellen nach links wird mit 4 multipliziert, bei drei mit 8, bei vier mit 16 usw.

Solche Bitverschiebungen können – abhängig vom System – bis zu 40(!)-mal schneller ablaufen als normale arithmetische Berechnungen im Stil von 4*x.


Galileo Computing - Zum Seitenanfang

8.5.6 Rechtsverschiebundowntop

Die Rechtsverschiebung mit dem >>-Operator ist das Gegenstück zur Linksverschiebung (<<). Damit können Sie statt einer Multiplikation mit 2 eine Division durch 2 bewirken. Ansonsten gilt das Gleiche wie für die Linksverschiebung.


Galileo Computing - Zum Seitenanfang

8.5.7 Rezept für Fortgeschrittene  toptop

Oft ist eine Funktion wünschenswert, mit der eine Zahl daraufhin getestet wird, ob ein bestimmtes Bit gesetzt ist, oder mit der sich gezielt einzelne Bits setzen oder löschen lassen. Hierzu ein Listing mit entsprechenden Funktionen:

/* playing_bits.c */
#include <stdio.h>
#define BYTE unsigned char
/* Funktion : Bit_Test()
 * val  : der Wert, den es zu testen gilt
 * bit  : Bitnummer, die abgefragt wird, ob gesetzt (0–7)
 * Rückgabewert :  (1)=Bit gesetzt; (0)=Bit nicht gesetzt
 */
int Bit_Test(BYTE val, BYTE bit) {
   BYTE test_val = 0x01;    /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   /* 0=Bit nicht gesetzt; 1=Bit gesetzt */
   if ((val & test_val) == 0)
      return 0;      /* Nicht gesetzt */
   else
      return 1;      /* gesetzt */
}
/* Funktion :  Bit_Set()
 * val  : Wert, bei dem Bit gesetzt werden soll
 * bit  : Bitnummer, die gesetzt werden soll (0–7)
 * Rückgabewert : keiner
 */
void Bit_Set(BYTE *val, BYTE bit) {
   BYTE test_val = 0x01;      /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   *val = (*val | test_val);     /* Bit an Pos bit setzen */
}
/* Funktion : Bit_Clear()
 * val  : Wert, bei dem Bit gelöscht werden soll
 * bit  : Bitnummer, die gelöscht werden soll (0–7)
 * Rückgabewert :  keiner
 */
void Bit_Clear(BYTE *val, BYTE bit) {
   BYTE test_val = 0x01;        /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   *val = (*val & (~test_val));   /* Bit an Pos bit löschen*/
}
int main(void) {
   BYTE wert = 0;
   /* Test, ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   Bit_Set(&wert, 0);    /* Bit 0 setzen */
   /* Wieder testen, ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   Bit_Clear(&wert, 0);  /* Bit 0 wieder löschen */
   /* Wieder testen ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   return 0;
}

Die Funktionen können natürlich den eigenen Bedürfnissen entsprechend angepasst werden und dienen nur als Anregung für weitere Spielereien mit Bits und Bytes.

 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de