Was bedeutet -ein- kaufmännisches Und(&) in verschiedenen Situationen?



  • Ich seh Code wie

    int bla = foo & bar; //foo sowie bar sind Integer

    oder

    if (foo & bar)
    {
    }

    Was 2 kaufmännische Unds' machen ist mir klar, aber was macht nur eins?

    Wenn ich im if unterschiedliche Werte für foo und bar einsetze, so ist das Ergebnis manchmal wahr, ich bin also innerhalb der geschweiften Klammern, manchmal nicht.

    Kann mir jemand also den Sinn & Zweck von einem & in Integern und Kontrollstrukturen etc. erklären?

    Vielen Dank!



  • Das &-Zeichen steht im Gegensatz zu && für ein bitweises UND, anstatt eines logischen UNDs.

    bitweise | logisch
       &     |    &&
       |     |    ||
       ^     |    (gibt's nicht!)
       ~     |    !
    

    Beispiel:

    01000100b & 11000000

    -->

    01000100
     11000000
     --------
     01000000
    

    Wenn beide Bits 1 sind, ist das Bit im Ergebnis auch 1, ansonsten 0

    Weiterhin kann das &-Zeichen aber auch auf eine Referenz hinweisen:

    int x = 0;
    int *y = &x; // y zeigt jetzt auf die Speicheradresse von x
    y = 2; // x hat jetzt den Wert 2, weil y auf die gleiche Adresse im Speicher verweist
    

    Genauso funktioniert dies auch bei Funktionsparametern (man übergibt nur eine Referenz auf das Objekt, um sich das Kopieren zu ersparen, dadurch ist es möglich, die Werte innerhalb der Funktion zu modifizieren):

    void add(int a, int b, int& result)
    {
        result = a + b;
    }
    

    Wie du siehst, wird hier nichts zurückgegeben, sondern das Ergebnis direkt in die per Parameter übergebene Referenz geschrieben (Das wird übrigens Call-by-Reference genannt, ansonsten heißt es Call-by-Value).

    Falls der Wert nun nicht geändert werden soll, empfiehlt es sich, result als const int& zu übergeben, wodurch es nicht geändert werden darf.



  • Helfer schrieb:

    ^     |    (gibt's nicht!)
    

    Die Semantik des XOR-Operators für zwei bool -Operanden kann man mittels operator!= hinkriegen.

    Helfer schrieb:

    Weiterhin kann das &-Zeichen aber auch auf eine Referenz hinweisen:

    int x = 0;
    int *y = &x; // y zeigt jetzt auf die Speicheradresse von x
    y = 2; // x hat jetzt den Wert 2, weil y auf die gleiche Adresse im Speicher verweist
    

    Das erste & in dem Code hat nichts mit einer Referenz zu tun. Ich fürchte, gerade bei solchen Dingen muss man sich sehr vorsichtig ausdrücken, damit man keine weitere Verwirrung stiftet.

    In C++ wird das Zeichen & in folgenden Kontexten eingesetzt. Es ist wichtig zu unterscheiden, ob es bei einem Typ steht oder als binärer bzw. unärer Operator auftritt. Je nachdem ist die Bedeutung anders.

    • expr & expr – Bitweiser Und-Operator.
    • type* var = &lvalue_expr; – Adressoperator. Gibt einen Zeiger auf den Ort im Speicher zurück, an dem der Operand liegt.
    • type& var = lvalue_expr; – Deklaration einer Referenz.

    Helfer schrieb:

    Falls der Wert nun nicht geändert werden soll, empfiehlt es sich, result als const int& zu übergeben, wodurch es nicht geändert werden darf.

    Nein, bei int lohnt sich eine Const-Referenz definitiv nicht. Das Objekt ist sehr schnell kopiert. Eine Referenz muss ebenfalls an die Funktion übergeben werden (das dürfte etwa gleich schnell wie die Kopie bei int sein), zusätzlich kommt aber noch der Overhead der Dereferenzierung dazu, den man bei einem Objekt nicht hat.

    Helfer schrieb:

    Genauso funktioniert dies auch bei Funktionsparametern (man übergibt nur eine Referenz auf das Objekt, um sich das Kopieren zu ersparen, dadurch ist es möglich, die Werte innerhalb der Funktion zu modifizieren):

    Bei dem Beispiel eben nicht, um die Kopie zu sparen, sondern um innerhalb der Funktion Zugriff auf die Originalvariable zu ermöglichen. Fürs Kopien-Sparen nimmt man eher Referenzen auf const -qualifizierte Objekte, und das auch nur bei grösseren Typen wie Klasseninstanzen.



  • Hallo,
    Referenzen kannte ich schon. Meine Frage bezog sich auf Kontrollstrukturen und die Verwendung in Integern, wobei letzteres beantwortet ist. Vielen Dank für die Erklärungen sie haben Licht ins Dunkle gebracht. Aber nicht alles ist geklärt

    01000100b & 11000000

    Warum steht denn ein b dort?

    Jedoch wurde auch die Frage zu den Kontrollstrukturen nicht beantwortet. Ich würde sehr gerne wissen, warum die Bedingung manchmal wahr und manchmal falsch ist.

    Mfg,
    TGRiX



  • Die bitweisen Operatoren operieren auf Integertypen und geben wieder Integertypen zurück. Wenn du nun so ein Resultat in einer if -, for -, while -, do-while -Bedingung hast, wird es implizit zu bool konvertiert. Dabei entsprechen alle Werte ungleich 0 true und die Null false .



  • Wieder was gelernt.

    Das b steht für binär, bei der zweiten Zahl hab ich's vergessen.

    Die Bedingung ist falsch, wenn zahl1 & zahl2 == 0 ist, ansonsten ist die Bedingung wahr (das Ergebnis wird nach bool gecastet, wobei 0 false und alles andere true entspricht)

    Die Zahlen müssen nicht unbedingt binär geschrieben werden - dies geschieht automatisch - , erleichtert das Verständnis der allgemeinen Abfolge durch diesen Befehl meines Erachtens aber. 🙂

    Ich hoffe, mir sind in diesem Posting nicht wieder so viele Verständnisfehler unterlaufen wie im vorherigen und entschuldige die durch den vorherigen Post eventuell entstandenen Verwirrungen 😉



  • Wie kommst du drauf, dass das ein gültiges Suffix ist?
    Im Standard habe ich nichts darüber gefunden. Und VS akzeptiert dsa korrekterweise auch nicht..
    Hmm. Ok, mir scheint so, als ob du das gar nicht auf ein Code Beispiel bezogen gemeint hast, aber warum schreibst dus dann? Ist doch aus dem Kontext klar. 😉



  • Hallo,

    die durch den vorherigen Post eventuell entstandenen Verwirrungen

    es entstanden keine Verwirrungen ;). Viele Dank für alle Antworten, damit wäre einiges geklärt.

    Aber: Wann haben binäre Operationen einen praktischen Anwendungsfall? Ich habe gelesen, dass dies zum Beispiel der Fall ist, wenn bestimmte Bits gesetzt werden sollen.
    XOR (^) desweiteren in einigen Verschlüsselungen, oft in Kombination mit OTPs.
    Gibts noch weitere?

    Mfg,
    TGRiX



  • Sind bei Flags gut.
    Zb wenn der Nutzer Optionen übergeben kann, die ge-AND-ed werden.



  • TGRiX schrieb:

    Aber: Wann haben binäre Operationen einen praktischen Anwendungsfall? Ich habe gelesen, dass dies zum Beispiel der Fall ist, wenn bestimmte Bits gesetzt werden sollen.

    Du musst vorsichtig mit der Terminologie sein. Unter binären Operatoren versteht man in erster Linie Operatoren mit zwei Operanden (im Gegensatz zu unären und dem einen ternären Operator in C++).

    Ja, für die Bearbeitung von einzelnen Bits. Bei sehr kritischen Anwendungen kann man durch bitweise Operationen möglicherweise Optimierungen erzielen (bezüglich Geschwindigkeit und Speicherverbrauch). Aber man benutzt sie schon eher selten, wenn man nicht hardwarenah programmiert.

    Icematix schrieb:

    Zb wenn der Nutzer Optionen übergeben kann, die ge-AND-ed werden.

    Du meinst ge-OR-ed. 😉



  • Danke für alle Antworten. Haben mir wirklich sehr geholfen.


Anmelden zum Antworten