Kann jemand mir dieses kleines Programm mit Array helfen



  • Cyres schrieb:

    Ich mag mich irren, aber ein "Schreiben Sie" vor den ersten Satz und ich lese eine komplette Aufgabenstellung 😉

    Es tut mir leid,das habe ich vergessen 🙂



  • SeppJ schrieb:

    Wie würdest du es denn derzeit machen? Zeig doch mal einen Versuch!

    int main(int argc, char argv)
    {
    int a[10];
    for(int i=0, i<=9, i++)
    a[i]=i
    i;
    return 0;
    }
    ich habe es so gemacht :D.


  • Mod

    Das ist doch ganz ok. Nun ersetzt du das Array durch einen Vector und du bist fertig.



  • SeppJ schrieb:

    Das ist doch ganz ok. Nun ersetzt du das Array durch einen Vector und du bist fertig.

    ja,aber das ist genau was,was ich noch nicht gemacht habe. Wie ersetze ich dieses Array durch einen Vektor und dieser Vektor auf dem Bildschirm ausgeben.
    Tut mir leid für meine dumme Frage 🙂


  • Mod

    Fangen wir mal klein an:
    Vector: Schonmal gehört? Schonmal gesehen? Zeig mal irgendein funktionierendes(!) Codebeispiel mit einem Vector, das du kennst. Es braucht gar nichts zu machen, ich möchte nur deinen Kenntnisstand sehen.



  • Wie wäre es damit?

    std::vector<unsigned> vec(10);
    std::iota(vec.begin(),vec.end(),1);
    std::transform(vec.begin(),vec.end(),[](unsigned x){return x * x});
    


  • TNA schrieb:

    Wie wäre es damit?

    Danke, dass du SeppJ's didaktische Herangehensweise zunichte machst. Nicht immer muss man mit seinen STL-Kenntnissen angeben 🙄



  • BLA _ schrieb:

    TNA schrieb:

    Wie wäre es damit?

    Danke, dass du SeppJ's didaktische Herangehensweise zunichte machst. Nicht immer muss man mit seinen STL-Kenntnissen angeben 🙄

    Vor allem wenn es absolut ineffizient ist, 3 mal über ein Array zu loopen. Hier wäre Boost.Range angebracht, sonst halt std::generate_n+lambda+static (was sogar noch kürzer wäre).


  • Mod

    BNA's Not BLA schrieb:

    Hier wäre Boost.Range angebracht, sonst halt std::generate_n+lambda+static (was sogar noch kürzer wäre).

    Am kürzesten und effizientesten (aber leider etwas unflexibel) wäre wohl die allereinfachste Lösung, auf die anscheinend noch niemand gekommen ist (komisch, ich hätte sie eigentlich innerhalb der ersten fünf Minuten als Antwort erwartet):

    std::vector<int> foo = {1,4,9,16,25,36,49,64,81,100};
    


  • BLA _ schrieb:

    TNA schrieb:

    Wie wäre es damit?

    Danke, dass du SeppJ's didaktische Herangehensweise zunichte machst. Nicht immer muss man mit seinen STL-Kenntnissen angeben 🙄

    Da hast du sicherlich recht. Ich konnte einfach nicht widerstehen.



  • BNA's Not BLA schrieb:

    Vor allem wenn es absolut ineffizient ist, 3 mal über ein Array zu loopen. Hier wäre Boost.Range angebracht, sonst halt std::generate_n+lambda+static (was sogar noch kürzer wäre).

    Effizienz spielt hier wohl eher keine Rolle, aber ich sehe auch nur 2 Schleifen. Der Konstruktor dürfte bei elementaren Datentypen keine Schleife beinhalten. Mit Boost kenne ich mich nicht aus, aber hört sich interessant an.


  • Mod

    TNA schrieb:

    aber ich sehe auch nur 2 Schleifen. Der Konstruktor dürfte bei elementaren Datentypen keine Schleife beinhalten.

    Doch, es wird schließlich "zero initialized". Das wird zwar bei Optimierung auf ein recht effizientes memset hinauslaufen (wenn es extremst clever ist(was ich nicht glaube), dann weiß es sogar, dass neue Speicherseiten bereits genullt sind), aber prinzipiell wird bei dir alles 3x angefasst.



  • SeppJ schrieb:

    Doch, es wird schließlich "zero initialized". Das wird zwar bei Optimierung auf ein recht effizientes memset hinauslaufen (wenn es extremst clever ist(was ich nicht glaube), dann weiß es sogar, dass neue Speicherseiten bereits genullt sind), aber prinzipiell wird bei dir alles 3x angefasst.

    Das ist interessant. ich habe mich schon öfter gefragt was passiert, wenn elementaren Datentypen defaultkonstruiert werden. Hatte eigentlich gedacht, da würde nichts passieren. Was passiert denn, wenn man den Autogenerierten Defaultkunstructor einer Klasse aufruft, die elementare Datentypen als Member beinhaltet? Werden die Member dann auch "zero initialized"?



  • Um mal Schlüsse aus euren Erklärungen zu ziehen:

    std::vector<int> vec;
    vec.reserve(5);
    std::generate_n(back_inserter(vec),5,foo());
    

    ist also schneller als

    std::vector<int> vec(5);
    std::generate_n(vec.begin(),5,foo());
    

    ?

    Das hätte ja sehr weitreichende Implikationen, wobe auch sehr seltsam wäre, dass STL-Algorithmen fast ausschließlich auf letztere Art gelehrt werden.


  • Mod

    TNA schrieb:

    Das ist interessant. ich habe mich schon öfter gefragt was passiert, wenn elementaren Datentypen defaultkonstruiert werden. Hatte eigentlich gedacht, da würde nichts passieren. Was passiert denn, wenn man den Autogenerierten Defaultkunstructor einer Klasse aufruft, die elementare Datentypen als Member beinhaltet? Werden die Member dann auch "zero initialized"?

    default- und zero-initialization sind zwei ganz verschiedene Sachen. Die Unterschiede stehen im Detail im Standard in Kapitel 8.5 erklärt. Wenn ich es richtig erklären wollte, wäre das zu viel. Für eine etwas weniger technische Beschreibung als im Standard (mit Beispielen zu allen Fällen!), verlinke ich mal auf:
    http://en.cppreference.com/w/cpp/language/initialization
    (Unterlinks verfolgen!)

    Beim vector werden, wenn man nichts anderes angibt, die Elemente value-initialized. Was dann für Basisdatentypen zero-initialized bedeutet.


  • Mod

    TNA schrieb:

    ich habe mich schon öfter gefragt was passiert, wenn elementaren Datentypen defaultkonstruiert werden.

    nichts (Konstruieren ist ohnehin der falsche Begriff).

    Elemente eines Containers, die nicht anders initialisiert werden werden value-initialisiert.
    Value-initialisierung ist Default-Initialisierung für Klassen mit nutzerdefiniertem Defaultkonstruktor, oder für Arrays die Value-Initialisierung jedes Elements, oder Zero- gefolgt von Default-Initialisierung sonst.

    Default-Initialisierung ist für Klassen mit nichttrivialem Defaultkonstruktor der Aufruf desselben, für Arrays Default-Initialisierung jedes Elementes, oder nichts sonst.

    Zero-Initialisierung ist
    - für skalare Typen die Initialisierung mit der der Konstante 0 (entsprechend konvertiert),
    - für Klassen die *Zero-*Initialisierung jeder Basisklasse und jedes nichtstatischen Members (nur des ersten im union-Fall) und die Initialisierung von Padding mit 0 bits,
    - für Arrays die Zero-Initialisierung jedes Elements,
    - für Referenzen nichts.



  • Danke camper, jetzt verstehe ich schon deutlich mehr. Was ich noch nicht verstehe ist was eine Zero-Initialisierung einer Klasse genau bedeutet. Kann man eine Klasse explizit Zero-Initialisieren und wie sähe das als Codezeile aus?

    EDIT: Beim zweiten mal lesen habe ich es verstanden denke ich.


  • Mod

    Kleine Ergänzung:
    Falls bei der Definition einer Variablen diese nicht explizit initilialisiert wird (fehlender Initialisierer, keine Erwähnung in der ctor-Initialisierungsliste, new ohne Initialisierer), so wird die betreffende Variable Default-Initialisiert.
    Eine leeres Klammerpaar () bzw. {} bedeutet dagegen stets Value-Initialisierung.

    Variablen mit statischer und thread-lokaler Lebensdauer bekommen automatisch eine Zeroinitialisierung beim Programmstart verpasst.



  • Das ist doch deutlich komplexer als gedacht.
    Also

    std::string S;
    

    ist nicht dasselbe wie

    std::string S();
    

    ? Also das zweite ist eine Value-Initialisierung? Was wird da in diesem Beispiel konkret anders gemacht?


  • Mod

    Das zweite ist eine Funktionsdeklaration.

    std::string() wäre ein value-initialized std::string.


Anmelden zum Antworten