Zugreifen auf die Bytes einer Integer in C



  • karim_dh schrieb:

    Der Wert wird aber leider nicht geändert !

    Irgendein Wert wird schon geändert werden.
    Aber nicht so, wie du es erwartest.

    Welche Werte gibst du denn ein? (für einen Test wäre es auch ok, die Parameter im Programm fest vorzugeben)

    Welchen Wert hat size (deiner Meinung nach)

    Was bezweckst du mit der for-Schleife?

    Welchen Wert hat denn newVal



  • Ich bin ganz neu in der Programmiersprache C und arbeite zum ersten mal mit Bytes und mir ist aufgefallen,nachdem ich eure Anmerkungen gelesen habe,dass der Code von mir voll falsch ist !

    int x = (array[2] >> (8*byteIndex)) & 0xff;
    

    Dieser Code habe ich im Internet gefunden,es sollte damit ein Byte einer Integer zurückgegeben werden ! das mit dem festen Index ist nur zum Testen,habe es vergessen rauszunehmen.



  • SeppJ schrieb:

    Das sieht so aus, als hättest du irgendwo Fetzen von Programmen, die die Aufgabe oder eine ähnliche Aufgabe lösen und zufällig zusammenkopiert, bis es irgendwie compilierte. Falls ja: Das ist nicht Programmieren und wird offensichtlich nicht funktionieren. Ich muss wohl hoffentlich nicht erklären, wieso.

    karim_dh schrieb:

    Dieser Code habe ich im Internet gefunden,es sollte damit ein Byte einer Integer zurückgegeben werden ! das mit dem festen Index ist nur zum Testen,habe es vergessen rauszunehmen.

    Gut geraten 👍



  • Beispiel, Gibt int als Bytes aus.

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


  • @ByteBuster Danke sehr,das hat mir sehr geholfen 🙂



  • ByteBuster schrieb:

    unsigned char b = *((unsigned char*)(&i)+s);
    

    Das ist natürlich Nonsens.

    int main () 
    { 
        int s,i = 0x12345678;
        const unsigned char *b=(unsigned char*)&i;
    
        for (s=0; s<sizeof(int); s++) 
        { 
            printf ("%x ", b[s]); 
        } 
    }
    


  • Wutz schrieb:

    ByteBuster schrieb:

    unsigned char b = *((unsigned char*)(&i)+s);
    

    Das ist natürlich Nonsens.

    Sorry, aber ich sehe es gerade nicht. Warum ist das Nonsens?

    Und inwiefern ist dein Code anders?



  • Printe schrieb:

    Wutz schrieb:

    ByteBuster schrieb:

    unsigned char b = *((unsigned char*)(&i)+s);
    

    Das ist natürlich Nonsens.

    Sorry, aber ich sehe es gerade nicht. Warum ist das Nonsens?

    Und inwiefern ist dein Code anders?

    Er will die Casterei nicht in der Schleife haben.

    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 mit dem Pointer kann aus verschiedenen Gründen zicken, wenn du eine komische CPU oder Speicherorganisation hast.



  • 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