Länge eines Arrays bestimmen



  • AJ schrieb:

    Natürlich bleibts jedem selbst überlassen, wie man es macht, aber empfehlenswerter sind Konstanten.

    Eher nicht (zumindest für den konkreten Fall). Erstens musst du für jedes Array eine extra Konstante anlegen. Einfach lästig und unnötig. Und zweitens, du musst immer noch darauf achten, dass bei einer Änderung des Arrays die Konstante aktualisiert wird. Klar kannst du die Konstante dafür auch mit dem array / array[0] Konstrukt initialisieren. Nur dann stellt sich die Frage, warum du nicht gleich ein entsprechendes Makro verwendest. Das einzige Problem beim Makro ist, dass du darauf achten musst, dass das Array vorher nicht in einen Zeiger umgewandelt wurde. Aber das ist immer noch unproblematischer, als sich mit Konstanten rumzuschlagen. Und in C++ kann man ja selbst dieses Problem noch eliminieren.



  • groovemaster schrieb:

    Eher nicht (zumindest für den konkreten Fall). Erstens musst du für jedes Array eine extra Konstante anlegen.

    Richtig, das musst du immer:

    ...
    int arr[5]; // => 5 ist auch eine Konstante
    ...
    

    Einfach lästig und unnötig.

    Unbedingt notwendig, siehe oben 😉

    Und zweitens, du musst immer noch darauf achten, dass bei einer Änderung des Arrays die Konstante aktualisiert wird.

    Musst du ja auch immer, siehe wieder oben.

    Klar kannst du die Konstante dafür auch mit dem array / array[0] Konstrukt initialisieren.

    😮 OMG! (Von hinten durch den Rücken ins Knie geschossen...)

    Aber das ist immer noch unproblematischer, als sich mit Konstanten rumzuschlagen. Und in C++ kann man ja selbst dieses Problem noch eliminieren.

    Mir stellt sich grad die Frage, ob du wirklich weißt, wie man Konstanten verwenden sollte.

    Beispiel:

    #define MAX_ZAHLEN 5 //in C++: const MAX_ZAHLEN = 5;
    ...
    arr_zahlen[MAX_ZAHLEN] = {0};
    ...
    for(i = 0 ; i < MAX_ZAHLEN; ++i)
    {
       ...
    }
    ...
    mach_was(arr_zahlen, MAX_ZAHLEN);
    ...
    

    Wenn ich jetzt die Größe des Arrays ändern will, dann brauch ich nur eine einzige Stelle anfassen und der Rest funktioniert trotzdem noch so wie es soll.



  • AJ schrieb:

    Richtig, das musst du immer:

    ...
    int arr[5]; // => 5 ist auch eine Konstante
    ...
    

    Naja, nicht immer. Die ursprüngliche Frage war ja, wie man die Größe bekommt, wenn man das array so anlegt:

    ...
    int arr[] = {1,2,3,...}; 
    ...
    

    Jetzt kann man sich eine Konstante anlegen, um sich die Größe zu merken. Die muss man aber manuell ändern, wenn man die Initialisierung des arrays ändert.
    Oder man machts mit sizeof und muß an diese Änderung nicht mehr denken.

    Warum jetzt die eine Variante fehleranfälliger sein soll als die andere, kann ich im Moment nicht erkennen.



  • AJ schrieb:

    Richtig, das musst du immer:

    ...
    int arr[5]; // => 5 ist auch eine Konstante
    ...
    

    Nein, muss ich nicht. Siehe Guybrush's Post. Zudem sprach ich vielmehr vom Bezeichner der Konstante, also dies hier

    #define MAX_ZAHLEN 5
    

    AJ schrieb:

    Einfach lästig und unnötig.

    Unbedingt notwendig, siehe oben 😉

    Nein. Siehe oben. 😉

    AJ schrieb:

    Und zweitens, du musst immer noch darauf achten, dass bei einer Änderung des Arrays die Konstante aktualisiert wird.

    Musst du ja auch immer, siehe wieder oben.

    Nein. Siehe Posts zuvor.
    Du legst EINMAL! das Makro an und es spuckt IMMER! die korrekte Grösse welchen Arrays auch immer aus. Da kannst du an den Arrays soviel rumschrauben wie du willst. Und irgendwelche Konstanten brauchst du auch nicht anfassen.

    AJ schrieb:

    Klar kannst du die Konstante dafür auch mit dem array / array[0] Konstrukt initialisieren.

    😮 OMG! (Von hinten durch den Rücken ins Knie geschossen...)

    Aber das ist immer noch unproblematischer, als sich mit Konstanten rumzuschlagen. Und in C++ kann man ja selbst dieses Problem noch eliminieren.

    Mir stellt sich grad die Frage, ob du wirklich weißt, wie man Konstanten verwenden sollte.

    Mir stellt sich die Frage, ob du überhaupt weisst, wovon ich rede.

    AJ schrieb:

    Beispiel:

    #define MAX_ZAHLEN 5 //in C++: const MAX_ZAHLEN = 5;
    ...
    arr_zahlen[MAX_ZAHLEN] = {0};
    ...
    for(i = 0 ; i < MAX_ZAHLEN; ++i)
    {
       ...
    }
    ...
    mach_was(arr_zahlen, MAX_ZAHLEN);
    ...
    

    Wenn ich jetzt die Größe des Arrays ändern will, dann brauch ich nur eine einzige Stelle anfassen und der Rest funktioniert trotzdem noch so wie es soll.

    Siehe Antwort zuvor.

    Da ich keine Lust habe mich weiter zu streiten, mach ich dir einen Vorschlag. Nimm eines der Arrays, die hier gepostet wurden (keine eigenen!) und zeige mir mit deinen Konstanten, wie du das Array änderst indem nur EINE! Stelle angepasst wird. Da du sizeof(array) / sizeof(array[0]) offenbar nicht magst, ist das für dich gestorben. Wenn du es mit weniger Anpassungen schaffst als ich, hast du gewonnen. Wenn nicht, dann lässt du es bleiben, und wir haken das ganze unter der Kategorie "auch ein Moderator kann sich irren" ab. Ok?
    Noch ein kleiner Tipp am Rande. Die Chancen, dass du gewinnst stehen ziemlich schlecht, da ich es mit genau EINER! Anpassung schaffe. Und da ich nicht davon ausgehe, dass du übernatürliche Kräfte besitzt, wirst du wohl mehr als 0 Anpassungen benötigen. Das soll dich aber nicht davon abhalten, es trotzdem zu probieren. Also mach dich mal ran...



  • @groovemaster
    Wer redet hier denn von Streit? 😮

    Ich fürchte du steigerst dich da ein wenig zu sehr rein. Nimm dein Makro wie üblich her, mir ist es egal.

    Ich weiß übrigens wovon ich rede und zwar von unterschiedlichen Programmiertechniken.

    Ich nehme das Konstrukt arr[] = { ... } einfach nicht her, dahingehend hab ich nicht das Problem die Größe später noch bestimmen zu müssen, denn ich weiß ja die Größe. Mal ganz davon abgesehen, dass ich es nicht logisch finde erst eine Größe festzulegen und sie dann später wieder ermitteln zu müssen. Auch bei arr[] = { ... } legst du eine feste Größe fest.

    GuybrushThreepwood schrieb:

    Warum jetzt die eine Variante fehleranfälliger sein soll als die andere, kann ich im Moment nicht erkennen.

    Paradebeispiel:

    #define arr_count(a) (sizeof(a)/sizeof(a[0]))
    ...
    int main(void)
    {
       int arr[] = {1, 2, 3};
    
       mach_was(arr);
    }
    
    void mach_was(int * arr)
    {
       printf("%d", arr_count(arr));
    }
    

    Mir ist klar, dass das die meisten nicht machen würden. Weil man schon entsprechende Erfahrung hat. Es geht mir hier aber auch nicht um die Leute, die schon Programmieren (speziell C) können, sondern um die Anfänger. Denn diese verwenden das Makro nicht mit dem nötigen Hintergedanken, weil sie es einfach nicht besser wissen.



  • AJ schrieb:

    Ich nehme das Konstrukt arr[] = { ... } einfach nicht her, dahingehend hab ich nicht das Problem die Größe später noch bestimmen zu müssen, denn ich weiß ja die Größe. Mal ganz davon abgesehen, dass ich es nicht logisch finde erst eine Größe festzulegen und sie dann später wieder ermitteln zu müssen. Auch bei arr[] = { ... } legst du eine feste Größe fest.

    Ja, das hat eine feste Größe, allerdings steht die nicht explizit im Quelltext - und an der Stelle benötigt man das sizeof-Konstrukt, um die Elementanzahl zu bestimmen.



  • groovemaster schrieb:

    Verpack das ganze noch in ein Makro und die Anwendung ist denkbar einfach.
    Jedes mal

    sizeof(array) / sizeof(array[0])
    

    zu schreiben, wäre mir zumindest auch zu nervig.

    Mach's doch lieber als Funktion. Ist schöner *scnr* 🤡



  • CStoll schrieb:

    AJ schrieb:

    Ich nehme das Konstrukt arr[] = { ... } einfach nicht her, dahingehend hab ich nicht das Problem die Größe später noch bestimmen zu müssen, denn ich weiß ja die Größe. Mal ganz davon abgesehen, dass ich es nicht logisch finde erst eine Größe festzulegen und sie dann später wieder ermitteln zu müssen. Auch bei arr[] = { ... } legst du eine feste Größe fest.

    Ja, das hat eine feste Größe, allerdings steht die nicht explizit im Quelltext - und an der Stelle benötigt man das sizeof-Konstrukt, um die Elementanzahl zu bestimmen.

    Wie gesagt, ich rede von unterschiedlichen Programmiertechniken. "Nötig" ist das sizeof-Konstrukt da auch nicht. Nur sinnvoller, wenn man nur eine Stelle anstatt zwei ändern will, mehr aber auch nicht.

    @TactX
    😃



  • @AJ
    Tja, hast dich mehr oder weniger ungekonnt um meinen Vorschlag gedrückt. Sei's drum, kann ja jeder selbst seine Schlüsse ziehen.

    AJ schrieb:

    Ich fürchte du steigerst dich da ein wenig zu sehr rein.

    Keine Sorge, ich steigere mich in nichts hinein. Das Gefühl hatte ich eher von dir. Darf ich dich deshalb daran erinnern, dass DU angefangen hast, gegen dieses sizeof Konstrukt zu wettern. Ich wollte das ganze nur zu einem Abschluss bringen, da es mir sinnlos erscheint, über sowas weiter zu streiten. Zumal feigling bereits eine korrekte Antwort gegeben hat und du mit deinem Einwand dem OP keinen Jota weitergeholfen hast.

    AJ schrieb:

    Ich weiß übrigens wovon ich rede und zwar von unterschiedlichen Programmiertechniken.

    Ach ja? Unter "unterschiedlichen Programmiertechniken" verstehst du, eine Konstante für die Länge eines Arrays zu definieren? Komisch. Ich verstehe darunter zB, ob man strukturiert oder OO programmiert. Aber da haben wir wohl andere Ansichten.

    AJ schrieb:

    Ich nehme das Konstrukt arr[] = { ... } einfach nicht her, dahingehend hab ich nicht das Problem die Größe später noch bestimmen zu müssen, denn ich weiß ja die Größe.

    Nur weil du etwas nicht benutzt, heisst das noch lange nicht, dass andere das auch nicht benutzen.

    AJ schrieb:

    Mal ganz davon abgesehen, dass ich es nicht logisch finde erst eine Größe festzulegen und sie dann später wieder ermitteln zu müssen. Auch bei arr[] = { ... } legst du eine feste Größe fest.

    Ja, das passiert aber für uns implizit durch die Initialisierung. Schon mal daran gedacht, dass für den Programmierer in gewissen Situation die Grösse absolut irrelevant ist? Und man genau deshalb auf solch ein unsized Array zurückgreift? Das Problem ist nur, dass man in gewissen Situationen die Länge halt trotzdem braucht, zB wenn man durch das Array iteriert.

    AJ schrieb:

    Paradebeispiel

    Und einziges Beispiel, das hatte ich aber bereits angesprochen. Zudem ist dies kein Argument für deine Konstanten. Oder verzichtest du generell auf Funktionalität, nur weil es bestimmte Fallstricke gibt? Da frage ich mich doch, warum du überhaupt C programmierst.

    AJ schrieb:

    Wie gesagt, ich rede von unterschiedlichen Programmiertechniken. "Nötig" ist das sizeof-Konstrukt da auch nicht. Nur sinnvoller, wenn man nur eine Stelle anstatt zwei ändern will, mehr aber auch nicht.

    Mehr schon, vor allem wenn es darum geht konsistenten Code zu schreiben. Dort schneided dieses sizeof Konstrukt allgemein besser ab. Nur nochmal zur Verdeutlichung:

    Array anlegen
      mit Konstante
        - Array definieren
        - Konstante definieren
      mit sizeof
        - Array definieren
    Array ändern
      unsized Array
        mit Konstante
          - Arrayinhalt ändern
          - Konstante ändern
        mit sizeof
          - Arrayinhalt ändern
      sized Array
        mit Konstante
          - Arrayinhalt ändern
          - Konstante ändern
        mit sizeof
          - Arrayinhalt ändern
          - Arraygrösse ändern
    

    Wie du siehst, hat man mit Konstante mehr Aufwand, mehr Sorgen und letztendlich mehr verloren als gewonnen.
    Aber im Gegensatz zu dir, will ich niemanden bekehren. Wenn du Konstanten verwenden willst, dann tu das. Aber behaupte nicht, dass es besser sei und man sich wundern solle, dass solche sizeof Konstrukte überhapt, und sehr oft sehr falsch, verwendet werden. Denn das ist schlichtweg Unsinn.

    TactX schrieb:

    Mach's doch lieber als Funktion.

    Keine Sorge, das mach ich. Liegt aber auch daran, dass ich eher C++ programmiere und dann gibts auch keine Fallstricke. 😉





  • Tja, ich interpretier das einfach mal als "getroffene Hunde bellen". Und damit können wir das Thema wohl abhaken.



  • AJ schrieb:

    CStoll schrieb:

    AJ schrieb:

    Ich nehme das Konstrukt arr[] = { ... } einfach nicht her, dahingehend hab ich nicht das Problem die Größe später noch bestimmen zu müssen, denn ich weiß ja die Größe. Mal ganz davon abgesehen, dass ich es nicht logisch finde erst eine Größe festzulegen und sie dann später wieder ermitteln zu müssen. Auch bei arr[] = { ... } legst du eine feste Größe fest.

    Ja, das hat eine feste Größe, allerdings steht die nicht explizit im Quelltext - und an der Stelle benötigt man das sizeof-Konstrukt, um die Elementanzahl zu bestimmen.

    Wie gesagt, ich rede von unterschiedlichen Programmiertechniken. "Nötig" ist das sizeof-Konstrukt da auch nicht. Nur sinnvoller, wenn man nur eine Stelle anstatt zwei ändern will, mehr aber auch nicht.

    Und wieso wehrst du dich dann dagegen, es einzusetzen, wenn es sinnvoller ist?
    Die Probleme des sizeof (gerade mit der Array-zu-Pointer-Umwandlung) sind bekannt*, die Vorteile auch - also sollte jeder selber abschätzen, was er verwenden will.
    (ich setze es z.B. so ein, daß ich die Größe des Arrays nach der Deklaration bestimme und mir merke - und da überwiegen dann die Vorteile)

    int vals[] = {...};
    const int valsize = sizeof(vals)/sizeof(vals[0]);
    ...
    berechne(vals,valsize);
    

    * bzw. sie sollten bekannt sein 😉



  • @CStoll
    Ich hab geschrieben: Es ist sinnvoller zu benutzen, wenn man nicht zwei Stellen ändern will sondern nur eine. Wobei das wiederrum das arr[] = { ... } Konstrukt voraussetzt, aber egal.

    CStoll (off) schrieb:

    also sollte jeder selber abschätzen, was er verwenden will.

    Das schreib ich doch schon die ganze Zeit.

    Wer lieber das sizeof()-Konstrukt verwenden will, der soll das tun. Ich persönlich würde es nie verwenden und auch nicht empfehlen. Warum man sich daran so aufhängt versteh ich ehrlich gesagt überhaupt nicht.

    groovemaster schrieb:

    Tja, ich interpretier das einfach mal als "getroffene Hunde bellen". Und damit können wir das Thema wohl abhaken.

    Wenn du meinst... 🙄

    Es heißt übrigens: "Nur betroffene Hunde bellen"
    Da wär ich aber nicht der einzige 🤡



  • AJ schrieb:

    @CStoll
    Ich hab geschrieben: Es ist sinnvoller zu benutzen, wenn man nicht zwei Stellen ändern will sondern nur eine. Wobei das wiederrum das arr[] = { ... } Konstrukt voraussetzt, aber egal.

    Und wie machst du es sonst, wenn du ein Array mit (z.B.) verschiedenen Parameterwerten festlegen willst?

    (btw, wozu gibt es denn das arr[]={...}? doch nur, damit sich der Programmierer keine Gedanken mehr machen muß, wieviele Werte in dem Array stehen.)



  • AJ schrieb:

    Es heißt übrigens: "Nur betroffene Hunde bellen"

    Da könnte man jetzt auch wieder drüber streiten. Man findet nämlich sehr wohl beide Formen, wobei meiner Erfahrung nach die getroffenen Hunde verbreiteter sind.

    Mit solchen absoluten Aussagen (wie auch "die sizeof-Variante ist immer schlechter") sollte man vorsichtig sein.



  • Hallo miteinander. Bin neu hier 🙂

    Hab gerade diesen Thread entdeckt. Da wir in der Technikerschule auch momentan mit Arrays rumprogrammieren hab ich mir das ganze hier mal durchgelesen. Eine Frage ist aber auf gekommmen:

    Kann mir jemand erklären was das ganze hier genau bedeutet:

    sizeof(array) / sizeof(array[0])
    

    Reicht nicht einfach das hier:

    sizeof(array)
    

    Was macht im ersten Beispiel das / sizeof(array[0]) ?
    Den / kenne ich bis jetzt nur als Geteilt-Funktion. Somit würde ich erstes Beispiel so interpretieren:
    Errechne Größe des Arrays und teile das Ganze dann durch die Größe des Arrays an der Stelle 0!

    Könnte mir das ganze einer erklären?

    mfg Alex



  • Errechne die Größe des gesamten Arrays und teile sie durch die Größe des ersten Elements => Was kommt raus? 😉



  • sizeof(array)
    

    liefert die Größe des Arrays in Byte

    sizeof(array[0])
    

    liefert die Größe des ersten Array-Elements (ebenfalls in Byte)

    Wenn du diese beiden Werte dividierst (ja, / ist die Division), erhältst du die Größe des Arrays in Elementen - also die Anzahl der Array-Elemente.



  • Ach so. Ich dachte das sizeof mir direkt die Anzahl der Elemente ausgibt *ganzdoofbin*

    Und die Größe der Elemente hängt vom Datentyp (int, double etc) ab oder?



  • AlexDozer schrieb:

    Und die Größe der Elemente hängt vom Datentyp (int, double etc) ab oder?

    Vom Datentyp, diese wiederum von der Implementierung. Sicher ist nur, dass sizeof(char) = 1 ist.


Anmelden zum Antworten