Zugreifen auf die Bytes einer Integer in C



  • Freund der Bytes schrieb:

    Er will die Casterei nicht in der Schleife haben.

    Kein Grund, den Code "Nonsens" zu nennen. Er ist doch korrekt, oder?

    So geht's auch noch:

    #include <stdio.h>
    
    int main ()
    {
        int i = 0x12345678;
        int s;
        for (s=0; s<sizeof(int); s++)
        {
            printf ("%x ", i & 0xff);
            i>>=8;
        }
    }
    

    Das ist nicht das gleiche. Durch die Schieberei werden die Originaldaten verändert.

    Das mit dem Pointer kann aus verschiedenen Gründen zicken, wenn du eine komische CPU oder Speicherorganisation hast.

    Was meinst du damit, beispielsweise?



  • Printe schrieb:

    Freund der Bytes schrieb:

    Er will die Casterei nicht in der Schleife haben.

    Kein Grund, den Code "Nonsens" zu nennen. Er ist doch korrekt, oder?

    Korrekt ist subjektiv. Er funzt jedenfalls.

    Printe schrieb:

    Das ist nicht das gleiche. Durch die Schieberei werden die Originaldaten verändert.

    Ja, wenn der int heile bleiben soll, musste du eine Kopie machen.

    Printe schrieb:

    Das mit dem Pointer kann aus verschiedenen Gründen zicken, wenn du eine komische CPU oder Speicherorganisation hast.

    Was meinst du damit, beispielsweise?

    [/quote]
    Erst mal die Endianess und dann könnte der Speicher für ints erst gar nicht Byte-adressierbar sein, usw. Das mit der Shifterei funktioniert überall gleich, das garantiert der C-Standard.



  • AusByter schrieb:

    Erst mal die Endianess und dann könnte der Speicher für ints erst gar nicht Byte-adressierbar sein, usw. Das mit der Shifterei funktioniert überall gleich, das garantiert der C-Standard.

    Wenn man mal ganz oben guckt, wie eigentlich die Aufgabe gestellt war, dann merkt man viellicht, dass das hier haarscharf am Thema vorbeigeht. Subjektiv natürlich.



  • Printe schrieb:

    AusByter schrieb:

    Erst mal die Endianess und dann könnte der Speicher für ints erst gar nicht Byte-adressierbar sein, usw. Das mit der Shifterei funktioniert überall gleich, das garantiert der C-Standard.

    Wenn man mal ganz oben guckt, wie eigentlich die Aufgabe gestellt war, dann merkt man viellicht, dass das hier haarscharf am Thema vorbeigeht. Subjektiv natürlich.

    Es sind eben lauter Denkanregungen für den OP. Datentypen als etwas anderes zu interpretieren ist immer kritisch.

    Auf 16 Bit CPU geht vielleicht nicht mal die 0x12345678 in ein int. Besser int32_t nehmen.

    Aber wenigstens ist ein sizeof() in der Schleife. Manche würden einfach eine 4 nehmen. Das wäre dann in der Tat alles andere als "korrekt", auch wenn es zufälligerweise geht.



  • Stechbytel schrieb:

    Es sind eben lauter Denkanregungen für den OP. Datentypen als etwas anderes zu interpretieren ist immer kritisch.

    Zitat aus der Aufgabenstellung: Ergänzen Sie das folgende Programm mittels Zeigerarithmetik so, dass das Byte an der Stelle byteIndex im Array-Element array[arrayIndex] auf den Wert neuerInhalt gesetzt wird.

    Ich denke, es ist sonnenklar, was hier verlangt ist, und es ist nicht hilfreich, Lösungen, die genau das machen, als "Nonsens" zu titulieren. Über Endianness, 16-Bit-CPUs und dergleichen soll man sich hier nicht den Kopf zerbrechen. Für eine Lösung mit Bitschiebereien könnte es sogar Punktabzug geben.



  • Du kannst als Ahnungsloser überhaupt nicht beurteilen, was sinnvoll ist oder nicht, ebenso wie dein Lehrer es nicht kann. Trolle dich an deine Uni und halte die Klappe.



  • Printe schrieb:

    Zitat aus der Aufgabenstellung: Ergänzen Sie das folgende Programm mittels Zeigerarithmetik so, dass das Byte an der Stelle byteIndex im Array-Element array[arrayIndex] auf den Wert neuerInhalt gesetzt wird.

    Dann bleibt quasi nur die Lösung:

    *((char*)&(array[arrayIndex])+byteIndex) = neuerInhalt;
    

    Sieht aber total hässlich aus.


  • Mod

    Schichtarbyter schrieb:

    Sieht aber total hässlich aus.

    Ich finde das gut. Alles Wesentliche in einem einzigen Ausdruck.



  • Schichtarbyter schrieb:

    Dann bleibt quasi nur die Lösung:

    *((char*)&(array[arrayIndex])+byteIndex) = neuerInhalt;
    

    Ich würde das lesbarkeitshalber mit Zwischenschritten machen (int-Pointer, char-Pointer und dann schreiben) und die Optimierung dem Compiler überlassen, aber Prinzip ja, das wäre der Weg.



  • Printe schrieb:

    Ich würde das lesbarkeitshalber mit Zwischenschritten machen (int-Pointer, char-Pointer und dann schreiben)

    Oder man versteckt das Gewurschtel in ein Makro ...

    #define BYTE_PTR(addr,offset) (*((char*)&(addr)+(offset)))
    

    und dann

    // Setzen 
    BYTE_PTR (array[arrayIndex], byteIndex) = neuerInhalt;
    // lesen
    printf ("%d", BYTE_PTR (array[arrayIndex], byteIndex));
    

Anmelden zum Antworten