[gelöst]Integerarray Länge bestimmen - Doch wie?



  • Hi Leute,

    habe bisher folgenden Ansatz :

    #include <stdio.h>
    #include <stdlib.h>
    
    int size_array_int (int array[])
    {
        return sizeof(array)/sizeof(int);
    }
    
    int main ()
    {
        int Array1[] = {0x41,0x42,0x43};
        int Array2[] = {0x4,0x4,0x4};
    
        printf("%d\n",size_array_int(Array1));
        printf("%d\n",size_array_int(Array2));
    
        return 0;
    }
    

    Doch irgendwie bekomme ich für beide
    Arrays den Wert 1? Eigentlich müsste
    es doch 3 sein... 😕
    Finde meinen Fehler nicht und hoffe
    auf eure Hilfe! 😞

    MfG Jonas 😃

    Edit:

    Gebe ich es so ein:

    printf("%d\n",sizeof(Array1)/sizeof(int));
    

    Doch die Frage besteht weiterhin, warum
    es nicht so wie oben geht?



  • Der Parameter array hat in der Funktion den Typ int* (auch wenn da int[] steht), deshalb kriegst du 1 raus. Was du vorhast, ist schlicht und einfach nicht möglich, du musst die Größe zusätzlich mit übergeben.



  • talas schrieb:

    Hi Leute,

    habe bisher folgenden Ansatz :

    int size_array_int (int array[])
    {
        // array ist hier nur noch ein Zeiger, demnach rechnest du sizeof zeiger / sizeof int
    }
    

    Anders ausgedrückt: Du kannst keine Arrays an Funktionen übergeben (, so dass sie "innen" auch noch Arrays sind). Hier könnte man evtl. ein Makro nehmen, oder halt einfach direkt den Ausdruck so stehen lassen. Tut auch nicht weh.

    #define ARRAY_ELEMENTS(x) (sizeof x / sizeof *x)
    


  • Tim schrieb:

    Hier könnte man evtl. ein Makro nehmen...Tut auch nicht weh.

    wie jetzt? du schlägst makros vor? ich dachte, du hasst die dinger.
    🙂



  • Ok danke Leute! 😉
    Wie siehts mit der Performance von Macros
    aus, genauso wie bei Funktionen oder
    langsamer/schneller?

    MfG Jonas



  • talas schrieb:

    Ok danke Leute! 😉
    Wie siehts mit der Performance von Macros
    aus, genauso wie bei Funktionen oder
    langsamer/schneller?

    kommt drauf an. meistens schneller, weil der funktionsaufruf entfällt. das was in makros links steht, wird vor'm compilen einfach gegen das ausgetauscht, was rechts steht.
    🙂



  • Danke schön.
    Habe mich für die Makrolösung entschieden!

    Aber eine Frage habe ich noch:
    Also wenn ich folgendes
    habe:

    int x; // ist *x der Typ also int?
    

    Oder wieso steht das so in dem Makro?
    Weil mit dem Stern, das sind doch Pointer??
    Das verwirrt mich noch etwas..

    MfG Jonas 🙂



  • talas schrieb:

    Weil mit dem Stern, das sind doch Pointer??

    ...beim anlegen von pointern. später dann heisst es 'inhalt von' und damit ist gemeint 'das, worauf der pointer zeigt'.
    🙂



  • talas schrieb:

    Oder wieso steht das so in dem Makro?
    Weil mit dem Stern, das sind doch Pointer??
    Das verwirrt mich noch etwas..

    Anfänger würden sowas im Code schreiben (Beweis siehe oben ;)):

    int arr[] = {0, 0, 0, 0};
    size_t n = sizeof(arr) / sizeof(int);
    

    Also Makro würde das so aussehen:

    #define ARRAY_ELEMENTS(x) (sizeof(x) / sizeof(int))
    
    int arr[] = {0, 0, 0, 0};
    size_t n = ARRAY_ELEMENTS(arr);
    

    Erst einmal vollkommen korrekt. Der Fehler tritt (u.U.) bei einer leichten Abwandlung des Codes auf:

    #define ARRAY_ELEMENTS(x) (sizeof(x) / sizeof(int))
    
    short arr[] = {0, 0, 0, 0};
    size_t n = ARRAY_ELEMENTS(arr);
    

    Oft ist sizeof(short) != sizeof(int), demnach würde in so einem Fall hier die falsche Länge des Arrays ermittelt werden. Als weitere Konsequenz könnte man das Makro nur (sinnvoll) auf int-Arrays anwenden. Diese Einschränkung ist aber nicht notwendig, da sizeof nicht nur auf Typen, sondern auch auf Ausdrücke angewendet werden kann. Diesen Umstand nutzen wir um sämtliche (störenden) Typinformationen aus dem Makro zu entfernen:

    #define ARRAY_ELEMENTS(x) (sizeof x / sizeof *x)
    
    short arr[] = {0, 0, 0, 0};
    size_t n = ARRAY_ELEMENTS(arr);
    

    *x ist hier eine einfache Dereferenzierung. Gleichbedeutend mit x[0].
    Dadurch sollte auch deutlich werden, dass das Makro hier keinen Sinn macht:

    #define ARRAY_ELEMENTS(x) (sizeof x / sizeof *x)
    
    int val = 0;
    size_t n = ARRAY_ELEMENTS(val);
    

    Klar, val ist ja auch kein Array. Gut aber, dass der Compiler hier einen Fehler bringen würde. Schlecht, dass Compilerfehler "in" Makros meistens etwas verwirrend sind.



  • Danke für die tolle ausführliche Erklärung
    von euch 😉
    Jetzt ist es mir klar!

    MfG Jonas 🙂



  • Ich hoffe ich komm nicht zu spät...
    Ich hab mir das mal überlegt und mit dem Hinweis von Bashar hats dann auch geklickt.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define ARRAY_MAX 5
    
    int size_array_int(int a[], int x);
    
    int main()
    {
        int count, arr[ARRAY_MAX];
    
        for(count = 0; count < ARRAY_MAX; arr[count++] = 1);
        printf("%d", size_array_int(arr, count));
        return 0;
    }
    
    int size_array_int(int a[], int x)
    {
        return (sizeof(a)*x/sizeof(int));
    }
    

    Wie auch immer du dein Array fülls, du brauchst was, was mitzählt um es dann an die Funktion zu übergeben.
    So wird ein Schuh draus 🙂

    Greetz



  • Ich hab da nochmal was vorbereitet. So gehts auch, aber du müsstest in deinem Beispiel eben den Pointer auch selbst auf das letzte Array-Element setzen.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define ARRAY_MAX 5
    
    int size_array_int(int * a, int *b);
    
    int main()
    {
        int count, arr[ARRAY_MAX], *pt_arr_end;
        pt_arr_end = &arr[ARRAY_MAX];
    
        for(count = 0; count < ARRAY_MAX; arr[count++] = 1);
        printf("%d", size_array_int(arr, pt_arr_end));
        return 0;
    }
    
    int size_array_int(int * a, int * b)
    {
        return ((unsigned long)(b - a));
    }
    

    Greetz


Anmelden zum Antworten