C++ Array Frage - Anfänger



  • Hallo,
    ich bin gerade dabei verschiedene Array-Beispiele auszuprobieren. Dabei bin ich auf Folgendes gestoßen:

     //  int ary[5];
       array<int, 5> ary{ 0, 1, 2, 3, 4 };
       ary[1] = 4;
       ary[3] = 5;
       std::cout << "Array Inhalt erst: ";
       for(int i = 0; i < 5; i++){
       std::cout << ary[i] << " ";
       }
    

    So kompiliert es und lässt sich ausführen und macht, was ich möchte.
    Aber so (nur die erste Zeile hat sich geändert):

       int ary[5];
    //   array<int, 5> ary{ 0, 1, 2, 3, 4 };
       ary[1] = 4;
       ary[3] = 5;
       std::cout << "Array Inhalt erst: ";
       for(int i = 0; i < 5; i++){
       std::cout << ary[i] << " ";
       }
    

    So kompiliert es nicht mehr und ich bekomme diese Fehlermeldung:

    "PoiPoi.cpp:79:8: error: request for member 'fill' in 'ary', which is of non-class type 'int [5]' ary.fill(0);"

    Ich verstehe nicht wirklich, was mir das sagen will.
    Könnte mir da vielleicht jemand helfen?

    Gruß, Georg



  • Die Änderung sollte für den gezeigten Code keinen Unterschied machen.

    Allerdings deutet die Fehlermeldung darauf hin, dass du irgendwo noch mehr Code hast, der letztlich den Fehler verursacht:

    "PoiPoi.cpp:79:8: error: request for member 'fill' in 'ary', which is of non-class type 'int [5]' ary.fill(0);"

    Ein int [5]-Array ist keine Klasse, die eine fill-Memberfunktion hat wie das bei einem std::array der Fall ist. Dieser Code muss ebenfalls angepasst werden, damit das funktioniert. Da bietet sich z.B. die freie Fuktion std:fill an. Die macht quasi dasselbe, lässt sich aber auch mit simplen C-style-Arrays wie int [5] verwenden.



  • @Finnegan sagte in C++ Array Frage - Anfänger:

    Allerdings deutet die Fehlermeldung darauf hin, dass du irgendwo noch mehr Code hast, der letztlich den Fehler verursacht:

    "PoiPoi.cpp:79:8: error: request for member 'fill' in 'ary', which is of non-class type 'int [5]' ary.fill(0);"

    Ja, du hast Recht. Ich habe zwei Zeilen zu wenig kopiert. Das hier hat noch gefehlt:

       fill(ary.begin(), ary.end(), 0)
    //   ary.fill(0);
    

    Beide Versionen habe ich ausprobiert - mit beiden kommt im 2. Fall die gleiche Fehlermeldung:
    "PoiPoi.cpp:78:31: error: request for member 'end' in 'ary', which is of non-class type 'int [5]' std::fill(ary.begin(), ary.end(), 0)"

    ...Die macht quasi dasselbe, lässt sich aber auch mit simplen C-style-Arrays wie int [5] verwenden.

    Willst du damit sagen, dass "int ary[5]" nicht das Gleiche ist wie "array<int,5> ary" ? Ist es einfach die Schreibweise, die den Unterschied macht? int ary[5] ist C und array<int, 5> ary ist C++ ?

    Gruß, Georg



  • @georgz sagte in C++ Array Frage - Anfänger:

    @Finnegan sagte in C++ Array Frage - Anfänger:

    Allerdings deutet die Fehlermeldung darauf hin, dass du irgendwo noch mehr Code hast, der letztlich den Fehler verursacht:

    "PoiPoi.cpp:79:8: error: request for member 'fill' in 'ary', which is of non-class type 'int [5]' ary.fill(0);"

    Ja, du hast Recht. Ich habe zwei Zeilen zu wenig kopiert. Das hier hat noch gefehlt:

       fill(ary.begin(), ary.end(), 0)
    //   ary.fill(0);
    

    Beide Versionen habe ich ausprobiert - mit beiden kommt im 2. Fall die gleiche Fehlermeldung:
    "PoiPoi.cpp:78:31: error: request for member 'end' in 'ary', which is of non-class type 'int [5]' std::fill(ary.begin(), ary.end(), 0)"

    Auch hier gilt das Argument, dass ein C-style-Array keine Klasse ist, die irgendwelche Member-Funktionen bereitsstellt. Weder fill noch begin oder end. Auch hier gibt es analog zu std::fill freie Funktionen, um die Start- und End-Iteratoren zu bestimmen:

    std::fill(std::begin(ary), std::end(ary), 0);
    

    Das alles funktioniert für C-style-Arrays allerdings nur, wenn der Typ von ary auch tatsächlich noch ein Array mit fester größe ist, also sowas wie int[5]. Solche Arrays können nämlich sehr leicht implizit in einen simplen Pointer (hier einen int*) konvertiert werden (Array-to-pointer decay).
    Besonders Funktionen der Form f(int a[]) sind da für Anfänger verwirrend, diese sind äquivalent zu f(int* a) und konvertieren den Parameter implizit in einen Pointer, wobei die Längeninformation aus dem Typ verschwindet. Da würden dann begin/end nicht mehr funktionieren, da diese nicht mehr wissen können, wo das Array zuende ist, wenn sie die Länge nicht kennen.

    ...Die macht quasi dasselbe, lässt sich aber auch mit simplen C-style-Arrays wie int [5] verwenden.

    Willst du damit sagen, dass "int ary[5]" nicht das Gleiche ist wie "array<int,5> ary" ? Ist es einfach die Schreibweise, die den Unterschied macht? int ary[5] ist C und array<int, 5> ary ist C++ ?

    Nein, die sind nicht dasselbe. int ary[5] ist ein pures C-artiges Array mit fixer Größe. Das ist kein Klassentyp und solche Arrays haben auch keine Member-Funktionen (Methoden).

    array<int, 5> ist hingegen eine Klasse aus der Standardbibliothek, welche solch ein simples Array mit fester Größe modelliert. Es verhält sich in allen wichtigen Punkten wie ein C-style-Array und kann de facto wie ein solches verwendet werden. Es bietet aber noch ein paar zusätzliche Funktionen wie eben diese fill und begin/end member und es ist etwas weniger fehleranfällig zu handhaben, da es eben nicht so leicht in einen trivialen Pointer zerfällt (Array-to-pointer decay) und seine Längeninformation immer mitführt.



  • @Finnegan

    Vielen Dank, das hat mir sehr weitergeholfen.

    Gruß, Georg


Anmelden zum Antworten