Wieso funktioniert das nicht?



  • Er erwartet dort konstante Ausdrücke, ist aber zu blöd zu erkennen, dass diese Ausdrücke eigtl konstant sind -> wirst nicht um zeiger + new/new[] + delete/delete[] herumkommen

    alternativ kannst du auch std::tr1::array bzw std::vector nutzen - würd ich dir so gar empfehlen ^^
    zusätzlich noch das, was firefighter scho geschrieben hat :>

    bb



  • Hi,

    unskilled schrieb:

    ....
    alternativ kannst du auch std::tr1::array bzw std::vector nutzen - würd ich dir so gar empfehlen ^^
    zusätzlich noch das, was firefighter scho geschrieben hat :>

    bb

    also muss ich jetzt echt mal sagen warum den Anfaengern immer solche Tips gegeben werden versteh ich nicht. Diese wollen sich doch erst mal mit der Sprache zurechtfinden und dann wenn sie wissen was ne Klasse und Methoden sind können sie doch umsteigen. Aber fuer denn Anfang ist doch das OK is wie er es macht oder ned?

    Wie gesagt versteh ich nicht. Wenn ihr nen guten Grund habt den Anfaenger dazu zu raten, lass ich mich gern einem besseren belehren 🙄.

    Blessed Love C0de4Fun



  • C0de4Fun schrieb:

    Hi,also muss ich jetzt echt mal sagen warum den Anfaengern immer solche Tips gegeben werden versteh ich nicht. Diese wollen sich doch erst mal mit der Sprache zurechtfinden und dann wenn sie wissen was ne Klasse und Methoden sind können sie doch umsteigen. Aber fuer denn Anfang ist doch das OK is wie er es macht oder ned?

    Wie gesagt versteh ich nicht. Wenn ihr nen guten Grund habt den Anfaenger dazu zu raten, lass ich mich gern einem besseren belehren 🙄.

    Blessed Love C0de4Fun

    In einer gewissen Form hast du Recht.Wobei man einem Anfänger natürlich auch sofort mit std::vector raten kann, WENN man ihm gezeigt hat wie es mit einem normalen Array geht.Wir haben die Lösung zu seinem Arrayzeugs gezeigt und somit konnten wir ihm eine besser Lösung mit der STL zeigen. 🙂



  • Danke für eure Antworten, das geht ja flott hier 🙂

    Firefighter schrieb:

    bin ein Neuling in der C++ Programmierung

    1.Mit was für einem Tutorial hast du gelernt?
    2.Deine Threadbeschreibung ist nicht gerade aussagekräftig.
    3.Du musst bei der erstellung von arrays immer die größe in Eckigen Klammern angeben.
    4. Naja über void main sag ich jetzt nichts 😃
    5.Anstatt char, solltest du vielleicht die für C++ geschaffene besser version std::string nutzen.
    dazu hier: http://www.cplusplus.com/reference/string/string/

    zu 1) Ich habe das Buch "C++ für Spieleprogrammierer" von Heiko Kalista.
    in diesem Buch wird eben dieses Beispiel durchgenommen, nur wird es im Buch so gemacht wie volkard (const int Breite = 3;)geschrieben hat. Ich hätt's halt mit einem Array versucht.
    Da ich schon jahrelang mit PHP programmiere war mir nicht ganz klar wieso der Compiler hier einen Fehler wirft.
    2) ok ich werde mich beim nächsten mal bemühen einen besseren Titel zu finden 😉
    3) Lt. meinem Buch kann man das machen, man muss es aber nicht weil der Compiler dann die Größe selbst ermittelt wenn sie nicht angegeben ist. Bei größeren Arrays die sich ständig ändern können wäre es ja nicht praktikabel wenn man jedes mal die Größe neu definieren müsste.
    4) was ist "falsch" daran? Ich könnte genau so gut int main() benutzen und halt eine 0 zurückgeben statt gar nichts.
    5) Alles klar 🙂

    @unskilled
    Wie würde dieses Beispiel mit Zeigern aussehen? Ich muss ja in jedem Fall die Definition per Array aufbrechen weil ich die enthaltenen Werte nicht für diesen Zweck verwenden kann.

    Dann hab ich unabhängig von diesem Problem noch eine Frage: Gibt es in C++ assoziative Arrays? In PHP könnte ich die 2 XY Parameter zB so definieren:

    $params = array("sizeX" => 6, "sizeY" => 6);
    

    und dann eben über $params["sizeX"] drauf zugreifen.


  • Administrator

    alex++ schrieb:

    Dann hab ich unabhängig von diesem Problem noch eine Frage: Gibt es in C++ assoziative Arrays? In PHP könnte ich die 2 XY Parameter zB so definieren:

    $params = array("sizeX" => 6, "sizeY" => 6);
    

    und dann eben über $params["sizeX"] drauf zugreifen.

    In C++ nennt sich sowas eine Map:
    http://www.cplusplus.com/reference/stl/map/

    Grüssli



  • Firefighter schrieb:

    In einer gewissen Form hast du Recht.Wobei man einem Anfänger natürlich auch sofort mit std::vector raten kann, WENN man ihm gezeigt hat wie es mit einem normalen Array geht.Wir haben die Lösung zu seinem Arrayzeugs gezeigt und somit konnten wir ihm eine besser Lösung mit der STL zeigen. 🙂

    wenn ich mich recht erinnere, sind vectors recht unhandlich, wenns um zweidimenionale geht.
    bitte schreib doch mal schnell den code

    Fieldinfo Spielfeld[ FieldsizeX ][ FieldsizeY ];
    

    so um, daß er std::vector benutzt. der rest des programms soll gleich bleiben können, gell?
    wenn der dann schrecklich aussieht, muß ich mich der frage anschließen, warum ihr immer solche unpassenden sachen vorschlagt.



  • Ok die bei der unhantlichkeit schließe ich mich an.Aber was würdest du dann empfehlen?Wenn doch anscheint eh immer alles falsch ist was wir hier vorschlagen?:D



  • volkard schrieb:

    wenn ich mich recht erinnere, sind vectors recht unhandlich, wenns um zweidimenionale geht.

    ähm... nein?
    ich seh da kein prob von wegen unhandlichkeit...
    außerdem könnte er zur not auch nen wrapper dafür bauen:

    struct 2darr
    {
     size_t DIM_x;
     std::vector <int> arr;
    
     const int& Get(size_t x, size_t y) const {return arr[DIM_X*x+y];}
     int& Get(size_t x, size_t y) {return arr[DIM_X*x+y];}
    };
    

    wenn wir schon mal bei wrapper sind:
    natürlich könnte man hier jz aber auch mit new/delete arbeiten - und wenn man schon mal dabei ist, dann kann man auch gleich boost::scoped_ptr nehmen:

    struct 2darr
    {
     size_t DIM_x;
     size_t DIM_y;
     boost::scoped_ptr <int*> arr;
    
     void resize()
     {
       arr = new int[DIM_x * DIM_y];
     }
    
     2darr(size_t x, size_t y) : DIM_x (x), DIM_y (y)
     {
       resize();
     }
    
     const int& Get(size_t x, size_t y) const {return arr[DIM_X*x+y];}
     int& Get(size_t x, size_t y) {return arr[DIM_X*x+y];}
    };
    

    Jz baut man noch nen assert bei Get() ein und schon ist man fertig...
    (na gut - man muss noch getter und setter für x/y bauen, die private machen, so was wie begin() + end() wär noch gut etc)

    bb



  • alex++ schrieb:

    1. was ist "falsch" daran? Ich könnte genau so gut int main() benutzen und halt eine 0 zurückgeben statt gar nichts.

    Genau, und so solltest du es auch machen (außer, dass das explizite return 0 bei main() nicht notwendig ist), denn du willst ja (hoffentlich) Standard-C++ programmieren und der Standard sagt nunmal

    C++ Standard, 3.6.1 schrieb:

    1. A program shall contain a global function called main, which is the designated start of the program. [...]
    2. An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int [...]
      [...]
    3. [...] If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

    Felix



  • Firefighter schrieb:

    Ok die bei der unhantlichkeit schließe ich mich an.Aber was würdest du dann empfehlen?Wenn doch anscheint eh immer alles falsch ist was wir hier vorschlagen?:D

    einfach auf dem teppich bleiben und den anfänger nicht in 21 tagen zum vollprofi machen. ich würde ihm empfehlen es so zu machen, wie ich ihm empfohlen habe, es zu machen.



  • unskilled schrieb:

    volkard schrieb:

    wenn ich mich recht erinnere, sind vectors recht unhandlich, wenns um zweidimenionale geht.

    ähm... nein?
    ich seh da kein prob von wegen unhandlichkeit...

    du hast ja auch den code nicht geschrieben, der diese initialisierung ausführt! machs doch endlich.

    unskilled schrieb:

    außerdem könnte er zur not auch nen wrapper dafür bauen:

    struct 2darr
    {
     size_t DIM_x;
     std::vector <int> arr;
    
     const int& Get(size_t x, size_t y) const {return arr[DIM_X*x+y];}
     int& Get(size_t x, size_t y) {return arr[DIM_X*x+y];}
    };
    

    da fehlt aber der zugriff per arr[3][4].
    DIM_x wird dem konstruktor übergeben? wo wird der speicher angelegt?
    DIM_X*x+y klingt unglaubwprdig. nicht eher DIM_X*y+x?
    also wenn du schon so viele fehler dabei machst, wie solls ein anfänger schaffen?

    unskilled schrieb:

    wenn wir schon mal bei wrapper sind:
    natürlich könnte man hier jz aber auch mit new/delete arbeiten - und wenn man schon mal dabei ist, dann kann man auch gleich boost::scoped_ptr nehmen:

    struct 2darr
    {
     size_t DIM_x;
     size_t DIM_y;
     boost::scoped_ptr <int*> arr;
    
     void resize()
     {
       arr = new int[DIM_x * DIM_y];
     }
    
     2darr(size_t x, size_t y) : DIM_x (x), DIM_y (y)
     {
       resize();
     }
    
     const int& Get(size_t x, size_t y) const {return arr[DIM_X*x+y];}
     int& Get(size_t x, size_t y) {return arr[DIM_X*x+y];}
    };
    

    Jz baut man noch nen assert bei Get() ein und schon ist man fertig...
    (na gut - man muss noch getter und setter für x/y bauen, die private machen, so was wie begin() + end() wär noch gut etc)

    und die dicken fetten fehler wegmachen, wie das new[]/delete. du darfst doch kein delete ohne klammern benutzen wo das new[] die klammern hatte. kopierkonstruktor und zuweisungsoperator noch verbieten, op[][] fehlt immernoch, DIM_y braucht eigentlich keiner. DIM_X*x+y ist weiterhin falsch.

    aber vor allem ist es kontraproduktiv und gar keine hilfe. sowas kann ein anfänger unmöglich hinkriegen. die einzigen wirkungen sind, daß er sich seinen stil versaut, weil er komplett im dunkeln tapst und über jede zufallslösung froh ist, und daß er die lust verliert. das wollen wir doch nicht.



  • @volkard, ok ich werd mir dein Rat zu herzen nehmen 😉



  • volkard schrieb:

    du hast ja auch den code nicht geschrieben, der diese initialisierung ausführt! machs doch endlich

    #include <vector>
    
    #include <cstdlib>
    using std::size_t;
    
    std::vector < std::vector <int> > arr;
    size_t x;
    std::cin >> x;
    size_t y;
    std::cin >> y;
    
    arr.reserve(x);
    
    for (size_t i(0); i != x; ++i)
    {
      std::vector <int> tmp (y);
      for (size_t j(0); j != y; ++j)
      {
        std::cout << "(" << i << " , " << j << ")" << std::endl;
        int val;
        std::cin >> val;
        tmp[j] = val;
      }
      arr.push_back (tmp);
    }
    

    volkard schrieb:

    da fehlt aber der zugriff per arr[3][4].

    den ich dir nie versprochen hatte - weil man ihn in 90% der fälle nich braucht...

    volkard schrieb:

    wie das new[]/delete.

    Hmm... ok - dann müssen wir dummerweise wohl new nutzen -.-

    volkard schrieb:

    kopierkonstruktor und zuweisungsoperator noch verbieten

    o rly?

    volkard schrieb:

    op[][] fehlt immernoch

    wo hab ich geschrieben, dass ich ihn bereitstellen werde?

    volkard schrieb:

    , DIM_y braucht eigentlich keiner

    na dann merk dir die dimensionen mal außerhalb iwie 😛

    volkard schrieb:

    . DIM_X*x+y ist weiterhin falsch

    jopp - hatte ganz oben nich drüber nachgedacht, wie rum... Und dann auch nich weiter drüber nachgedacht...



  • vor resize wird eigentlich immer die größe gesetzt. also sollte resize einfach die größe selber als parameter kriegen und selber setzen. setX/setY ist als setXY besser, da der code simpel das gemeinsame unterrechteck kopiert, unterrechtecksgröße mit std::min finden. assert nicht auslagern, weil auslagern die meldungen abschwächt. delete[] auch nicht, weil delete[] hier sprechender ist als cleanup().
    hast übrigens wieder schwere fehler eingebaut. cleanup macht nicht arr = nullptr, was zu absturz führt, wenn einer ein array anlegt, es mit SetX(0) cleant und mit nem anderen füllt. SetX kopiert zu viel, absturz.
    nicht anfängerfreundlich. aber du willst bestimmt nicht sagen, daß ein anfämger sowas versuchen sollte, jetzt wo der wrapper ganz und gar nicht mehr einfach gehalten ist.
    und der andere code macht immer noch nicht, was

    Fieldinfo Spielfeld[ FieldsizeX ][ FieldsizeY ];
    

    macht. er liest irgendwelche sachen von der standardeingabe und so ein quatsch. und er levt nicht im global scope. ich suche ein replacement für obige anfängergeeignete zeile und nicht ein programm, das was total anderes macht.



  • Jopp - das mit dem nullptr hatte ich ja noch vor deinem Beitrag gemacht, aber iwie hab ich gerade mal versucht, das ganze zu testen und hab noch paar viele Fehler bekommen :-S
    Ich werds mal rauseditieren - wollte eigtl au noch was produktives heute machen... Aber vll bau ichs au iwann mal und stells wieder rein, damit du wieder was zum aufregen hast 😛

    bb



  • viel toller wäre ein möglichst einfacher ersatz für das eingebaute array und das eingebaute 2d-array, der auch nicht mehr kann, außer einem assert drin. aber der op[][] müßte schon sein.
    dann kann der anfänger sein bubblesort und seine einmaleinstabelle bauen und kriegt die so schwer zu findenden arraygrenzenüberschreitungen gemeldet.
    aber verschwende keine zeit mehr an die vector-lösung. die fühlt sich nicht gut an.



  • was ist an std::vector so schlimm? diese ganzen wrapper sind viel komplexer.

    struct Fieldinfo
    {
        char name[30];
        bool besetzt;
    };
    
    const int Fieldsize[] = {6, 6};
    
    std::vector< std::vector< Fieldinfo > > Spielfeld(Fieldsize[1], std::vector< Fieldinfo >(Fieldsize[0]));
    
    int main()
    {
    	Spielfeld[1][1].besetzt = true;
    }
    

    geht ohne probleme.

    auch mit volkards [][] operator 🙂

    und das teil hat nen assert 🙂 🙂



  • ich gebe zu: das ist gut.



  • volkard schrieb:

    viel toller wäre ein möglichst einfacher ersatz für das eingebaute array und das eingebaute 2d-array, der auch nicht mehr kann, außer einem assert drin.

    Das gibt es schon längst. Heißt std::tr1::array bzw. boost::array, falls die C++ Lib älter ist.


Anmelden zum Antworten