Funktionen und Arrays



  • Danke schon mal für das vielen Antworten.

    Ich hab den Quellcode oben nochmal korrekt zusammengefasst.
    C++ möchte ich lernen.

    @Schlangemensch: Die 5 Zeilen versteh ich überhaupt nicht. Am Anfang hatte ich nur ein 1D Array und ich konnte das wunderbar in eine Funktion geben. Dann wollte ich das in 2D machen und es hat nicht mehr geklappt. Ich musste feststellen, dass ich kein 2D Array an eine Funktion geben kann. Ich habe ewig gesucht und bin irgendwie nicht schlauer geworden, wie man das korrekt macht. Dann hab ich das in einem Forum gefunden und es probiert und es hat geklappt ^^

    Bei meinem ungekürzten Programm hatte ich ein Array mit Größe 720x720 maximal geschafft zu erzeugen. Aber dadurch konnte ich nur noch 100 Schritte machen bevor es abgestürzt ist.

    Zeiger^^ Ich finde das ja noch sehr verwirrend.

    Was ist die korrekte Methode ein 2D Array an eine Funktion zu geben?


  • 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