Zugreifen auf die Bytes einer Integer in C



  • Ich habe eine Programmieraufgabe in der Probeklausur der Programmiersprache C bekommen und komme nicht auf die richtige Lösung !
    Kann Jemand helfen ? Das Programm soll vervollständigt werden ! ich habe die Fragestellung genau so eingegeben wie es in der Probeklausur vorgekommen ist >>

    Gegeben sei das folgende Programm: Ein Array array mit zehn Elementen wird definiert. Der Nutzer gibt drei Indizes ein: einen Array-Index arrayIndex, einen Byte-Index byteIndex und einen Wert neuerInhalt.
    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. Gehen Sie davon aus, dass korrekte Werte eingegeben werden (keine Pru¨fung erforderlich).

    #include <stdio.h>
    int main() {
    
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int arrayIndex, byteIndex, neuerInhalt;
    
    printf("Welches Element im Array? "); 
    scanf("%d", &arrayIndex);
    
    printf("Welcher Byte im Element? "); 
    scanf("%d", &byteIndex);
    
    printf("Auf welchen Wert soll das Byte ge¨andert werden? "); 
    scanf("%d", &neuerInhalt);
    
    }
    


  • Wenn du nicht in der Lage bist das selbt zu lösen fällst du zurecht durch die Klausur!



  • etwa so:
    ((byte*)int_array)[n] = x;

    n ist der byte-offset.

    "byte" musste noch typedeffen, üblicherweise als "unsigned char"



  • @flatterjochen Das ist nicht die einzige Frage in der Klausur, sondern die schwerigste und ich habe das ja selber versucht die Frage zu lösen weiß aber nicht ob ich das richtig mache,deswegen habe ich die Frage gestellt !

    @Bytus ich probiere das mal 👍



  • karim_dh schrieb:

    ... ich habe das ja selber versucht die Frage zu lösen weiß aber nicht ob ich das richtig mache,deswegen habe ich die Frage gestellt !

    Dann wäre es sinnvoll gewesen, du hättest deine Lösung gezeigt und zur Diskussion gestellt.



  • Ich habe versucht,das so zu lösen :

    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
      int arrayIndex , byteIndex;
    
      printf("Welches Element im Array? ");
      scanf("%d" , &arrayIndex);
      size_t size = sizeof(array[arrayIndex]);
    
      printf("Welcher Byte im Element? "); 
      scanf("%d" , &byteIndex);
      int x = (array[2] >> (8*byteIndex)) & 0xff;
    
      int neuerInhalt;
      printf("Auf welchen Wert soll das Byte ge¨andert werden? ");
      scanf("%d" , &neuerInhalt);
    
      int newVal ;
      for(int i = 0 ; i < size ; i++){
        if(i == byteIndex){
          newVal += neuerInhalt;
        }else{
         newVal += (array[arrayIndex] >> (8*i)) & 0xff;
        }
      }
      array[arrayIndex] = newVal;
      printf("%d" , array[arrayIndex]);
    

    Der Wert wird aber leider nicht geändert !


  • Mod

    Deine Zeile 10 kann doch nicht einmal im Ansatz richtig sein. Wieso sollte eine Bytemaske vom Inhalt deines Arrays abhängen, noch dazu von der festen Position 2 im Array?

    Deine Zeilen 17-25 gehen komplett an der Aufgabenstellung vorbei. Du veränderst den eingegebenen Wert in Abhängigkeit von den Werten im Array, aber die Aufgabe ist, die Werte im Array in Abhängigkeit vom neuen Wert zu ändern!

    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:

    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.


Anmelden zum Antworten