Funktionen und Arrays


  • Mod

    Kasora schrieb:

    C++ möchte ich lernen.

    Dann mach hier Stopp. Vergiss all den Müll, den du über Zeiger und Arrays gehört hast und besorg dir stattdessen vernünftiges Lehrmaterial für C++. Nichts von alledem, was du hier gezeigt hast, würde man jemals in C++ benutzen. In C++ würde man die Container der Standardbibliothek benutzen. Die funktionieren ganz ohne komische Sonderregeln. Das heißt, du musst keine Verrenkungen anstellen, um sie in Funktionen zu benutzen, sondern es geht so einfach wie einen int an eine Funktion zu übergeben. Entsprechend sinkt auch das Fehlerpotential gewaltig.



  • Hi, ich habe mal ein grobes Grundgerüst zusammen geschrieben, damit du einen Einstieg hast.

    #include <iostream>
    #include <vector>
    
    double Function(const std::vector< std::vector <int > >& v) {
    
      return 42.; //Irgendwas was du berechnet hast...
    }
    
    int main() {
    //  Foo foo;
      const int size_i = 10;
      const int size_j = 10;
      std::vector< std::vector <int > > Array(size_i, std::vector<int>(size_j));
    
      //Als Beispiel, wie man durch ein Vektor von Vektoren durch iterieren kann
      for (auto& a : Array) {
        for (auto& number : a) {
          number = 42;
        }
      }
    
      double result = Function(Array);
    
      for (auto a : Array) {
        for (auto number : a) {
          std::cout << number << std::endl;
        }
      }  
    }
    

    Auch für die rand() Funktion gibt es inzwischen bessere Alternativen: http://www.cplusplus.com/reference/random/



  • Schlangenmensch schrieb:

    std::vector< std::vector <int > > Array(size_i, std::vector<int>(size_j));
    

    Das ist fast immer falsch; so auch hier.



  • Fytch schrieb:

    Schlangenmensch schrieb:

    std::vector< std::vector <int > > Array(size_i, std::vector<int>(size_j));
    

    Das ist fast immer falsch; so auch hier.

    Du willst mir auch bestimmt mitteilen, was daran falsch ist. Damit ich denselben Fehler nicht mehrfach mache.

    Etwas schöner wäre evt.

    std::vector< std::vector <int > > Array(size_i, std::vector<int>(size_j, 0));
    

    Dann ist auch jedes Element sicher mit 0 initialisiert.



  • Ich glaube, fytch möchte sowas sehen:

    vector<int> arr( 10 * 10 );
    

    und dann bei Elementzugriff den 2D Index auf einen linearen Index umrechnen.



  • Genau. Der semantische Unterschied zwischen std::vector< std::vector< int > > und std::vector< int > für 2D-Arrays ist, dass die erste Variante unterschiedlich lange Spalten erlaubt, was oftmals nicht erwünscht ist. Ferner braucht sie mehr Speicher und ist i.d.R. ineffizienter.



  • Ah cool danke. Lese mich jetzt in Vectoren ein und spiele damit rum.

    Ein paar Fragen hätte ich da noch:
    Was macht in der Zeile:
    double Function(const std::vector< std::vector <int > >& v) das & ???
    Warum schreibt man nicht
    double Function(const std::vector< std::vector <int>> V)

    Und was macht das auto& ??



  • Moin,
    ich hab gestern abend noch meine gesammten Quellcodes auf Vectoren umgeschrieben.
    Leider hat das den Fehler nicht behoben. Aber ich habe endlich den Fehler gefunden.

    ChooseX = static_cast<int> (lange*((double)rand() / (RAND_MAX)));
    

    Mit viel Pech wähle ich das Element "lange", aber das Array(jetzt Vektor) geht ja nur bis (lange-1). Dafür hab ich so lange gesucht in meinem Programm^^
    Jetzt komm ich mir voll dämlich vor. xD



  • Nimm besser eine std::uniform_int_distribution , dann ist auch sofort auf den ersten Blick klar, welche Range da zurückkommt. Dieses rumrechnen mit rand*irgendwas ist nicht nur fehleranfällig, sondern es liefert auch nicht exakt gleichverteilte Werte.

    Schlangenmensch hatte dich auch schon darauf hingewiesen, nicht rand() zu verwenden. Siehe auch (fun-Video): https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful Deine benutzte Formel ist in dem Video übrigens auch drin - und warum man sie NICHT benutzen sollte!



  • Kasora schrieb:

    Ah cool danke. Lese mich jetzt in Vectoren ein und spiele damit rum.

    Ein paar Fragen hätte ich da noch:
    Was macht in der Zeile:
    double Function(const std::vector< std::vector <int > >& v) das & ???
    Warum schreibt man nicht
    double Function(const std::vector< std::vector <int>> V)

    Und was macht das auto& ??

    Mit dem "&" werden Referenzen gekennzeichnet. Im Prinzip wird die Speicheradresse übergeben, wo die Variable liegt. Damit spart man sich, eine eventuelle teure Kopie. Und "const" damit man die Variable nicht verändern kann, sondern nur lesend drauf zugreifen.
    Bei dem "auto" Keywort is es ähnlich. "auto" leitet selbst den Variablen Typ her. Durch das "&" bekommst du eine Referenz. Damit die Änderungen die an den Variablen aus dem Vektor gemacht werden, auch wieder im Vektor ankommen.

    Fytch schrieb:

    Genau. Der semantische Unterschied zwischen std::vector< std::vector< int > > und std::vector< int > für 2D-Arrays ist, dass die erste Variante unterschiedlich lange Spalten erlaubt, was oftmals nicht erwünscht ist. Ferner braucht sie mehr Speicher und ist i.d.R. ineffizienter.

    Hm, wenn ich tatsächlich eine Matrix haben will, stimme ich dir da zu. Allerdings würde ich da wahrscheinlich zu einer entsprechenden Bibliothek (z.B. Eigen), greifen, denn die Umrechnung ist noch ein Punkt mehr, an dem man Fehler einbauen kann.
    Natürlich kann man das ganze auch selber kapseln und sich eine eigene Matrix Klasse schreiben, aber da war mir ein einfaches, "wie kann man mit std::vector arbeiten" Beispiel wichtiger.


Anmelden zum Antworten