|= und +=



  • Hallo Forum,

    was macht diese Zuweisung(?) genau |= und += bzw. was ist der unterschied?
    Waere fuer eine Erklaerung dankbar(bitte ohne dumme kommentare, jeder hat mal angefangen HI).

    mfg Olli.



  • "a += b;" ist das gleiche wie "a = a + b;". Du addierst den Wert b zu a dazu und weist das Ergebnis dieser Addition wieder a zu.

    "a |= b;" ist analog zum ersten Beispiel das gleiche wie "a = a | b". "|" ist der Operator für ein bitweises OR, d.h. der Computer geht den Inhalt beider Variablen auf binaerer Ebene durch und immer wenn bei min. einer der Variablen eine 1 steht, setzt er im Ergebnis auch eine 1. Dieses Ergebnis wird dann auch wieder a zugewiesen.



  • Hallo,
    a += b ist semantisch äquivalent zu a = a + b.
    a |= b zu a = a | b.

    | ist das bitweise-Oder. Bei a |= b wird also jedes Bit von a mit dem entsprechenden Bit von b oder-verknüpft. Das Ergebnis wird dann wiederum a zugewiesen.



  • also koennte man sich das bildlich so vorstellen;

    a |= b = 3
    a |= b = 5
    a |= b = 7
    a |= b = 2

    a hat ein wert von 3572



  • Ne, das leider nicht. Bitweises OR ist kein Aneinanderhängen o.ä.

    Hier mal ein Beispiel wie OR arbeitet:

    Sagen wir, Du hast zwei unsigned chars a = 3 und b = 5. Binaer dargestellt sieht der Inhalt von a und b so aus:

    a: 0000 0011
    b: 0000 0101
    

    Wenn Du a und b nun mit einem bitweisen OR verknüpfst, kommt folgendes (c) raus:

    a: 0000 0011  // a | b wird durchgeführt
    b: 0000 0101  
    ------------
    c: 0000 0111
    

    c hat jetzt - dargestellt im Dezimalsystem - den Inhalt 7 und nicht 35 o.ä.



  • Jo danke und ein Beispiel mit += waere super, danke

    mfg Olli.



  • daa531 schrieb:

    Jo danke und ein Beispiel mit += waere super, danke

    Wie oben schon gesagt:

    a x= b; ist das selbe wie a=a x b;
    wobei x ein beliebiger Operator sein kann.

    a=1
    b=2

    a+=b;

    a=3



  • Shade Of Mine schrieb:

    a x= b; ist das selbe wie a=a x b;
    wobei x ein beliebiger Operator sein kann.

    x = = => a == b; => a = a = b;

    (scnr)



  • Daniel E. schrieb:

    x = = => a == b; => a = a = b;
    (scnr)

    Ausnahmen bestätigen die Regel :p



  • @Daniel E.

    Shade Of Mine schrieb:

    wobei x ein beliebiger Operator sein kann.

    Die Rede war von Operatoren nicht von Zuweisungszeichen 😉



  • = ist ein Operator.



  • Naja wie man es sieht. Aber eigentlich hast recht. Man sagt ja auch Zuweisungsoperator.



  • Hallo Forum,

    irgendwie verstehe ich das nicht, sorry.

    /************************************************************************
     * Function        : 32 Bits aus einem Buffer lesen
     *
     * Inputs        : Zeiger auf den Buffer
     *
     * Returns        : unsigned long integer
     *
     * Operation    : Liest 2 Words und vertauscht sie
     *----------------------------------------------------------------------*/
    ULONG
    get32(MBHEAD *mbhd)
    {
      ULONG           retval;
    
        retval =  ((ULONG)getchr(mbhd)) << 24;
        retval |= ((ULONG)getchr(mbhd)) << 16;
        retval |= ((ULONG)getchr(mbhd)) << 8;
        retval |= (ULONG)getchr(mbhd);
    	return (retval);	return (retval);
    }
    

    Im Buffer ist eine IP-Adresse (3232261150) die ich mit get32 auslese.

    #include <stdio.h>
    int main()
    {
    unsigned long ipa =     3232261150;
    
    printf("%u.%u.%u.%u\n",
            (unsigned)(ipa >> 24),
            (unsigned)((ipa >> 16) & 0xff),
            (unsigned)((ipa >> 8) & 0xff),
            (unsigned)(ipa & 0xff));
    }
    

    Die Ausgabe ist (3232261150) 192.168.100.30.
    Unter Linux funktioniert alle super.
    Nun muss das aber unter Win32 genauso funktionieren !!!

    Unter Win32 bekomme ich einen anderen Wert 4289225758 bzw. dementsprechend
    eine andere IP-Adresse 255.168.100.30.

    Hier sind mal die retval-Werte:
    retval = ((ULONG)getchr(mbhd)) << 24; = 3221225472 (192.0.0.0)
    retval |= ((ULONG)getchr(mbhd)) << 16; = 4289200128 (255.168.0.0)
    retval |= ((ULONG)getchr(mbhd)) << 8; = 4289225728 (255.168.100.0)
    retval |= (ULONG)getchr(mbhd); = 4289225728 (255.168.100.30)

    Was ich nicht verstehe wo der die 255 her nimmt....

    Hier ist noch die getchr-funktion:

    ************************************************************************
    *                                                                        *
    * parameter  : mbhd    - Zeiger auf Kopf des Messagebuffers, aus dem     *
    *                        das Zeichen gelesen werden soll                 *
    *                                                                        *
    * r/o globals: -                                                         *
    *                                                                        *
    * r/w globals: -                                                         *
    *                                                                        *
    * locals     : -                                                         *
    *                                                                        *
    * returns    : aus dem Buffer gelesenes Zeichen                          *
    *                                                                        *
    \************************************************************************/
    char
    getchr(MBHEAD *mbhd)
    {
      if (mbhd->mbgc++ % sizeof_MBDATA == 0)
        mbhd->mbbp = ((MB *)((MAX_BUFFER huge *)(mbhd->mbbp) - 1))->nextmb->data;
      return (*mbhd->mbbp++);
    }
    

    Gruss Olli.



  • Hallo,

    daa531 schrieb:

    Was ich nicht verstehe wo der die 255 her nimmt....

    wenn man die Regeln beim type-cast von "signed" auf "unsigned" Typen nicht berücksichtigt, kann es ganz schnell Überraschungen geben, meine Erklärung:

    beim cast von char (der hier wohl "signed" ist) auf ULONG passiert "sign-extension" (wie im ANSI-Standard festgelegt), d.h., das Vorzeichen wird auf die höherwertigen Bits "ausgedehnt", oder anders ausgedrückt, die höherwertigen Bits werden alle zu eins. Deswegen wird bei diesem Schritt:

    retval |= ((ULONG)getchr(mbhd)) << 16;
    

    die 168, die ja vom Typ char ist (Rückgabewert von getchr ist char!), als vorzeichenbehaftet betrachtet, und nach dem cast in ULONG ist der Wert verfälscht (wegen der Vorzeichen-Expandierung), und du darfst dich nicht wundern, daß ein nachfolgendes binäres OR zum Wert 255 im höchstwertigen Byte führt (da dort nur Einsen im aus dem cast entstandenen ULONG-Wert stehen). Bei den restlichen Operationen:

    retval |= ((ULONG)getchr(mbhd)) << 8;
        retval |= (ULONG)getchr(mbhd);
    

    hast du einfach nur Glück gehabt, da sowohl 100, als auch 30, kein gesetztes Vorzeichenbit haben, so daß die oben beschriebene Wertverfälschung nicht stattfinden konnte. (Beim ersten Schritt war keine Gefahr, da dort zwar auch mit der 192 eine vorzeichenbehaftete Zahl vorlag, aber es sich sowieso um das höchstwertige Byte handelte).

    Lange Erklärung, kurzer Sinn: definiere den Rückgabewert von getchr als "unsigned char", und das Problem kann gar nicht erst entstehen:

    [b]unsigned char[/b]
    getchr(MBHEAD *mbhd)
    {
      if (mbhd->mbgc++ % sizeof_MBDATA == 0)
        mbhd->mbbp = ((MB *)((MAX_BUFFER huge *)(mbhd->mbbp) - 1))->nextmb->data;
      return (*mbhd->mbbp++);
    }
    

    das könnte das Problem gewesen sein...

    MfG



  • Hallo Probe-Nutzer,

    das könnte das Problem gewesen sein...

    genau das war das Problem !!! Vielen vielen Dank !!
    Nun geht auch alles unter win32.

    wenn man die Regeln beim type-cast von "signed" auf "unsigned" Typen nicht berücksichtigt, kann es ganz schnell

    Gibt es im Internet eine ausfuehrliche Dokumentation ueber "type-cast" ?
    Ich habe zwar hier ein C Buch, aber keine Informationen von type-cast.

    mfg Olli.



  • es geht eigentlich nicht nur um die "Gefahren" des type-casts, vielmehr können solche Umwandlungen auch implizit passieren. Der folgende Link enthält alle diese Regeln, auch die, die in deinem Falle "zugeschlagen" hat (ist dort nicht ganz so einfach ausgedrückt, wie ich es geschrieben habe, aber man kann sich leicht überlegen, daß die Beschreibung dort letztlich eine "sign-extension" für diesen Fall bedeutet):

    http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V40F_HTML/AQTLTBTE/DOCU_067.HTM

    MfG


Log in to reply