5 Stimmen

Einige zufällige C-Fragen (ascii-Magie und bitweise Operatoren)

Ich versuche, die C-Programmierung zu erlernen, und ich habe einige Quellcodes studiert, und es gibt einige Dinge, die ich nicht verstanden habe, insbesondere in Bezug auf Bitwise-Operatoren. Ich habe einige Seiten dazu gelesen und irgendwie eine Vorstellung davon bekommen, was sie tun, aber als ich zurückging, um mir diese Codes anzusehen, konnte ich nicht verstehen, warum und wie sie verwendet wurden.

Meine erste Frage bezieht sich nicht auf die bitweisen Operatoren, sondern auf einige Ascii-Zaubereien:

  1. Kann mir jemand erklären, wie der folgende Code funktioniert?

    char a = 3;
    int x = a - '0';

    Ich verstehe, dass dies getan wird, um ein Char in ein Int zu konvertieren, aber ich verstehe die Logik dahinter nicht. Warum/Wie funktioniert das?

  2. Was nun die Bitwise-Operatoren betrifft, so fühle ich mich hier wirklich verloren.

    • Was bewirkt dieser Code?

      if (~pointer->intX & (1 << i)) { c++; n = i; }

      Ich habe irgendwo gelesen, dass ~ Bits invertiert, aber mir ist nicht klar, was diese Anweisung tut und warum sie das tut.

      Dasselbe gilt für diese Zeile:

      row.data = ~(1 << i);
    • Andere Frage:

      if (x != a)
        {
          ret |= ROW;
        }

      Was genau bewirkt der Operator |=? Von dem, was ich gelesen habe, ist |= OR, aber ich verstehe nicht ganz, was ist diese Anweisung tun.

      Gibt es eine Möglichkeit, diesen Code so umzuschreiben, dass er leichter zu verstehen ist und nicht diese bitweisen Operatoren verwendet? Ich finde sie sehr verwirrend zu verstehen, daher hoffe ich, dass mich jemand in die richtige Richtung weist, um zu verstehen, wie sie besser funktionieren!


Ich habe jetzt ein viel besseres Verständnis für bitweise Operatoren und der ganze Code macht jetzt viel mehr Sinn.

Eine letzte Sache: Anscheinend hat niemand geantwortet, ob es einen "saubereren" Weg gibt, diesen Code so umzuschreiben, dass er leichter zu verstehen ist und vielleicht nicht auf "Bit-Ebene". Irgendwelche Ideen?

17voto

Daniel Earwicker Punkte 111630

Dies führt zu Schrott:

char a = 3; 
int x = a - '0';

Dies ist anders - beachten Sie die Anführungszeichen:

char a = '3'; 
int x = a - '0';

El char Datentyp speichert eine Zahl, die ein Zeichen identifiziert. Die Zeichen für die Ziffern 0 bis 9 stehen alle nebeneinander in der Zeichencodeliste. Wenn Sie also den Code für "0" vom Code für "9" subtrahieren, erhalten Sie die Antwort 9. Auf diese Weise wird ein Ziffernzeichencode in den ganzzahligen Wert der Ziffer umgewandelt.

(~pointer->intX & (1 << i))

Dies wird von der if Anweisung als wahr, wenn sie ungleich Null ist. Es werden drei verschiedene bitweise Operatoren verwendet.

Der Operator ~ spiegelt alle Bits der Zahl um. pointer->intX était 01101010 entonces ~pointer->intX wird 10010101 . (Beachten Sie, dass ich hier den Inhalt eines Bytes darstelle. Wenn es sich um eine 32-Bit-Ganzzahl handeln würde, müsste ich 32 Ziffern mit 1en und 0en schreiben).

Der Operator & kombiniert zwei Zahlen zu einer Zahl, indem er jedes Bit einzeln behandelt. Das resultierende Bit ist nur dann 1, wenn beide Eingangsbits 1 sind. Wenn also die linke Seite 00101001 und die rechte Seite ist 00001011 wird das Ergebnis sein 00001001 .

Endlich, << bedeutet Linksverschiebung. Wenn Sie mit 00000001 beginnen und es um drei Stellen nach links verschieben, erhalten Sie 00001000. Der Ausdruck (1 << i) ergibt also einen Wert, bei dem das Bit i eingeschaltet ist und die anderen alle ausgeschaltet sind.

Alles zusammengenommen testet es, ob bit i ist ausgeschaltet (Null) in pointer->intX .

So können Sie vielleicht herausfinden, was ~(1 << i) tut. Wenn i es 4 wird die Sache in Klammern sein 00010000 und so wird die ganze Sache 11101111 .

ret |= ROW;

Das ist gleichbedeutend mit:

ret = ret | ROW;

El | Operator ist wie & mit der Ausnahme, dass das resultierende Bit 1 ist, wenn eines der Eingangsbits 1 . Wenn also ret es 00100000 y ROW es 00000010 wird das Ergebnis sein 00100010 .

0voto

Albert Punkte 538

ret |= ROW;

ist gleichbedeutend mit

ret = ret | ROW;

0voto

tstenner Punkte 9596

Einfache Anführungszeichen werden verwendet, um anzuzeigen, dass ein einzelnes Zeichen verwendet wird. 0' ist also das Zeichen '0', das den ASCII-Code 48 hat. 3-'0'=3-48

1<<i' verschiebt 1 um i Stellen nach links, so dass nur das i-te Bit von rechts 1 ist.
~pointer->intX negiert das Feld intX, so dass das logische UND einen wahren Wert (nicht 0) zurückgibt, wenn bei intX jedes Bit bis auf das i-te Bit von rechts nicht gesetzt ist.

0voto

Josh Weatherly Punkte 1678
char a = '3';  
int x = a - '0';

Sie haben sich hier vertippt (beachten Sie die 's um die 3), dies weist der char-Variablen den ascii-Wert des Zeichens 3 zu, dann nimmt die nächste Zeile '3' - '0' und weist sie x zu, aufgrund der Art und Weise, wie ascii-Werte funktionieren, ist x dann gleich 3 (ganzzahliger Wert)

Im ersten Vergleich habe ich noch nie gesehen, dass ~ auf diese Weise in einem Zeiger verwendet wird, vielleicht ein weiterer Tippfehler? Wenn ich den folgenden Code auslesen würde:

(~pointer->intX & (1 << i))

Ich würde sagen "(der vom Zeiger dereferenzierte Wert intX) AND (1 linksverschoben i mal)"

1 << i ist eine schnelle Methode, um 1 mit einer Potenz von 2 zu multiplizieren, d.h. wenn i gleich 3 ist, dann ist 1 << 3 == 8

In diesem Fall habe ich keine Ahnung, warum Sie die Bits des Zeigers invertieren sollten.

Im 2. Vergleich ist x |= y das Gleiche wie x = x | y

0voto

dwc Punkte 22998

Para char a = 3; int x = a - '0'; Ich glaube, Sie meinten char a = '3'; int x = a - '0'; . Das ist leicht zu verstehen, wenn man sich vergegenwärtigt, dass in ASCII die Zahlen in der Reihenfolge '0', '1', '2', ... stehen. Wenn also '0' 48 und '1' 49 ist, dann ist '1' - '0' 1.

Die bitweisen Operationen sind schwer zu verstehen, bis man anfängt, die Bits zu betrachten. Wenn Sie diese Operationen an Binärzahlen betrachten, können Sie genau sehen, wie sie funktionieren...

010 & 111 = 010
010 | 111 = 111
010 ^ 111 = 101
~010 = 101

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X