Begrüßung und erste Frage!



  • MichaelMAS schrieb:

    Gugelmoser eine Frage zum letzten Ding:

    Normal müsste dies einen Fehler verursachen, da man für nicht-dynamische Arrays als Größenangabe eine Compiletime-Konstante benutzen muss (also eine Zahl, die zur Kompilation bekannt ist und konstant ist):

    Stimmt, haste recht, da habe ich wohl ein kleines x statt ein großes gelesen. Da siehst du auch gerade, dass man Namen wohl besser nicht klein und groß geschrieben verwenden sollte, da man schnell mal durcheinander kommt. 😉



  • asc schrieb:

    Belli schrieb:

    Wieso funktioniert das hier eigentlich:
    ...
    wenn printf im Namensraum std liegt? (VSE2009)

    VSE2009 kenne ich zwar nicht (wenn 2008 oder 2010), aber wenn mein Englisch nicht sehr schlecht ist, würde ich aus dem Draft es so lesen, das der VSE hier nicht ganz richtig ist.

    Du hast natürlich recht: VSE2008 (Visual C++ 9.0) ... aber ...
    mein g++ (3.4.5) übersetzt es auch ohne Murren ...



  • So wie ich das sehe, hast du ein 8x8 Feld. 😉

    if (xkonv>0 && xkonv<9 && bamy>0 && bamy<9)
         feld[xkonv][bamy]='x'; // feld[8][8] könnte entstehen... Speicherzugriffsverletzung
    


  • Toll!
    Jetzt verstehe ich das mit dem einzeiligen Befehl bei if/else bzw. bei einer for schleife! Bau ich ein, das spart dann wieder Platz!

    Das mit dem A(ASCII 65) ist mir auch klar. Denn wenn 0 rauskommt und bei 0 bricht die Schleife ab --> Klar das es nicht funktioniert!

    DANKE DERWEIL!

    Dieses Programm ist derweil mal soweit erledigt und meine Fragen geklärt!

    Ihr seid alle miteinander toll und ich hoffe nächstes mal kann ich ein bereits "optimierteres" Programm an euch übergeben um etwaige Fragen zu stellen!

    lg

    Michael



  • Mein Programm jetzt:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <time.h>
    
    using namespace std;
    
    const int X=8;
    const int Y=8;
    
    int main()
    {
      srand(time(NULL));
    
      int x,y,z,konvx,konvy,ende;
      char bamx,bamy,feld[X][Y];
      int schiffx=(rand()%6);
      int schiffy=(rand()%8);
    
      for(y=0;y<Y;y++)
      {
            for(x=0;x<X;x++)
                feld[x][y]='.';
      }
    
      for (z=0;z<3;z++)
           feld[schiffx+z][schiffy]='o';
    
      do
      {
         cout<<"\n A B C D E F G H\n";
         for(y=0;y<Y;y++)
         {
            cout<<y+1;
            for(x=0;x<X;x++)
                cout<<feld[x][y]<<" ";
            cout<<"\n";
      }
    
      cout<<"\nZielkoordinaten eingeben: ";
      cin>>bamx>>bamy;
      konvx=bamx - 'A';
      konvy=bamy - '1';
    
      if (konvx>=0 && konvx<9 && konvy>=0 && konvy<9)
      {
         feld[konvx][konvy]='-';
         if (konvy==schiffy)
         {
            if  (konvx==schiffx || konvx==schiffx+1 || konvx==schiffx+2)
                 feld[konvx][konvy]='x'; cout<<"\nTREFFER\n";
         }
         else {cout<<"\nDANEBEN\n";}
      }
      else
      {
         ende=0;
      }
      }
      while(ende!=0);
      getchar();
    }
    


  • Belli schrieb:

    Du hast natürlich recht: VSE2008 (Visual C++ 9.0) ... aber ...
    mein g++ (3.4.5) übersetzt es auch ohne Murren ...

    GCC G++ 4.3.4 murrt.
    CodeGear 2009 murrt.



  • Es tut mir leid, wenn ich mich missverständlich ausgedrückt habe. Mein Hinweis bezog sich weniger auf eine Zeile, sondern mehr auf eine Prozedur bzw. Anweisung, denn in einer Zeile können auch mehrere Prozeduren zusammengepresst werden, von denen nur die erste von der for -Schleife bzw. if -und else -Überprüfung ausgewertet wird. D.h., wenn man das so schreibt:

    if  (konvx==schiffx || konvx==schiffx+1 || konvx==schiffx+2)
                 feld[konvx][konvy]='x'; cout<<"\nTREFFER\n";
    

    dann wird nur feld[konvx][konvy]='x'; ausgeführt, wenn eine der if-Bedingungen zutreffen. In diesem Fall gibt es zwei Anweinsungen (Wertzuweisung und cout), die in geschweifte Klammer gepackt werde sollten.

    Eins solltest du noch wissen: C++-Standard schreibt vor, dass die int main() -Funktion einen Rückgabewert zurückgeben muss. Wenn sie nicht 0 zurückgibt, wird die Ausführung vom System als fehlerhaft interpretiert.

    Nochmal zu

    if (konvx>=0 && konvx<9 && konvy>=0 && konvy<9)
    

    Da dein Array 8 Elemente hat, geht der Index von 0 bis 7. Für deine if-Überprüfung heißt es:

    if (konvx>=0 && konvx<8 && konvy>=0 && konvy<8)
    


  • Das mit dem <8 habe ich noch vergessen vorhin, stimmt -->DANKE

    Aber das mit dem nur die erste Anweisung wird ausgeführt bzw. umgesetzt verstehe ich zwar, aber bei mir funktioniert es trotzdem.

    if  (konvx==schiffx || konvx==schiffx+1 || konvx==schiffx+2)
                 feld[konvx][konvy]='x'; cout<<"\nTREFFER\n";
    

    Aber Treffer wird immer angezeigt!

    Was stimmt jetzt? Oder liegt das daran, dass ich DEV C++ verwende?



  • MichaelMAS schrieb:

    Aber Treffer wird immer angezeigt!

    Genau. Das liegt aber nicht am Compiler, sondern daran, dass nur die erste Anweisung durchgeführt wird, wenn if(...) zutrifft. Das bedeutet, dass "cout" unabhängig von if ausgeführt wird. Dazu müsstest du die Klammern setzen (weil es zwei Befehle sind, jeder endet ja mit Semikolon ";"):

    if  (konvx==schiffx || konvx==schiffx+1 || konvx==schiffx+2)
            {
                 feld[konvx][konvy]='x'; 
                 cout<<"\nTREFFER\n"; 
            }
    


  • Stimmt!
    Ja du hattest recht!

    Jetzt versteh ichs!

    Hab übersehen das immer TREFFER kommt auch wenn ich nicht treffe!

    DANKE



  • Die lokale Benutzung von Variablen und die Initialisierung solltest du noch umsetzen. Un für meinen Geschmack könnte an manchen Stellen ein Leerzeichen für bessere Lesbarkeit sorgen.

    #include <iostream> 
    #include <cstdlib> 
    #include <cstdio> 
    #include <ctime>  // statt time.h
    
    using namespace std; 
    
    const int X=8; 
    const int Y=8; 
    
    int main() 
    { 
      srand(time(NULL)); 
    
      char feld[X][Y]; 
      int schiffx=(rand()%6); 
      int schiffy=(rand()%8); 
    
      for( unsigned int y = 0; y < Y; y++) // lokale Zählvariable y
      {
          for( unsigned int x = 0; x < X; x++) // lokale Zählvariable x
          {
             feld[x][y]='.'; 
          }
      }
      for( unsigned int z = 0; z < 3; z++) // lokale Zählvariable z
      {
         feld[schiffx+z][schiffy]='o';  
      }
    
      bool Ende = false;
      do 
      { 
         cout<<"\n A B C D E F G H\n"; 
         for( unsigned int y = 0; y < Y; y++) // lokale Zählvariable y
         { 
            cout<<y+1; 
            for( unsigned int x = 0; x < X; x++) // lokale Zählvariable x
            {
                cout<<feld[x][y]<<" "; 
            }
            cout<<"\n"; 
         } 
    
         cout<<"\nZielkoordinaten eingeben: "; 
         int bamx = 0; // bamx, bamy werden erst hier benötigt, also auch erst hier definieren
         int bamy = 0; 
         cin>>bamx>>bamy; 
         int konvx=bamx - 'A'; // siehe bamx, bamy
         int konvy=bamy - '1'; 
    
         if( konvx >= 0 && konvx < 9 && konvy >= 0 && konvy < 9 ) 
         { 
            feld[konvx][konvy]='-'; 
            if( konvy==schiffy ) 
            {
               if( konvx==schiffx || konvx==schiffx+1 || konvx==schiffx+2 ) 
               {
                  feld[konvx][konvy]='x'; cout<<"\nTREFFER\n"; 
               }
               else 
               {
                  cout<<"\nDANEBEN\n";
               }
            }
         } 
         else 
         { 
            Ende = true; 
         } 
      } 
      while( !Ende ); 
      getchar(); 
    }
    


  • Ah..

    Bin wohl bei den ganzen Vorschlägen bei dem hier auf der Leitung gestanden.
    Das erleichtert die Auswahl an Zählern ungemein und man kommt nicht so leicht durcheinander! Diese unsigned int variablen sind also nur zum zählen und können daher zuvor undefiniert aufgerufen werden!
    Toll!
    Und dann kann ich doch zb. für alle for-Schleifen unsigned i verwenden, oder?
    Ich definiere ja immer nur für eine Schleife und nicht global davor!



  • und die Idee mit der boolschen Variable ist auch gut!
    Wozu sonst sind True/False da!
    Dieses Programm ist ja förmlich prädestiniert um zu veranschaulichen wie man das verwenden kann in c++ 😃

    THX



  • Man könnte auch noch die Arrays(c) durch Vektoren(c++) ersetzen. Vektoren bieten eine viel höhere Funktionalität als Arrays.

    Wenn du mit Wahrheitswerten arbeiten willst, würde sich evtl. ein boolscher Vektor anbieten.
    Beispiel:

    #include <vector>             //notwendige Bibliothek
    
    std::vector<bool> myvector(n);     // n ist die Anzahl der Elemente, grds. 
                                       // alle auf false gesetzt.
    

    Zugreifen kann man wie bei Arrays über den Index oder aber besser über einen sogenannten Iterator. Da es neben Vektoren noch andere Datenstrukturen (Container) gibt, hat man Iteratoren eingerichtet, die als Zugriff auf diese die gleiche Schnittstelle verwenden.

    Ergänzung:

    //Iterator einrichten
    std::vector<bool>::iterator pos;
    //Gibt alle Elemente aus
    for(pos=myvector.begin();pos !=myvector.end();++pos)
     {
       cout<<" "<<*pos;
     }
    

    s. auch

    http://www.cplusplus.com/reference/stl/vector/
    http://www.cplusplus.com/reference/std/iterator/



  • MichaelMAS schrieb:

    Oder liegt das daran, dass ich DEV C++ verwende?

    Dazu möchte ich noch loswerden, dass DevC++ nicht empfehlenswert ist. Gründe findest du hier: http://www.c-plusplus.net/forum/237002



  • Als Ergänzung zu redrew99 sei noch der Container std::array erwähnt, der sich intern exakt wie ein rohes Array verhält, aber viel sicherer und komfortabler ist. Es gibt in modernem C++ eigentlich keinen Grund mehr, die Arrays aus C zu verwenden.

    int x[5];
    // wird zu
    std::array<int, 5> x;
    

    Ohne die Standardbibliothek von C++0x kann man auch std::tr1::array oder boost::array einsetzen.



  • Nexus schrieb:

    Als Ergänzung zu redrew99 sei noch der Container std::array erwähnt, der sich intern exakt wie ein rohes Array verhält, aber viel sicherer und komfortabler ist. Es gibt in modernem C++ eigentlich keinen Grund mehr, die Arrays aus C zu verwenden.

    int x[5];
    // wird zu
    std::array<int, 5> x;
    

    Ohne die Standardbibliothek von C++0x kann man auch std::tr1::array oder boost::array einsetzen.

    👍



  • Können wir bitte mal mit diesem sinnlosen "Gefällt mir" aufhören? Wenn du etwas zu meinem Post zu sagen hast, dann schreib einen Satz mit Aussagekraft dazu.



  • Nexus schrieb:

    Können wir bitte mal mit diesem sinnlosen "Gefällt mir" aufhören? Wenn du etwas zu meinem Post zu sagen hast, dann schreib einen Satz mit Aussagekraft dazu.

    👎



  • Nexus schrieb:

    Als Ergänzung zu redrew99 sei noch der Container std::array erwähnt, der sich intern exakt wie ein rohes Array verhält, aber viel sicherer und komfortabler ist. Es gibt in modernem C++ eigentlich keinen Grund mehr, die Arrays aus C zu verwenden.

    int x[5];
    // wird zu
    std::array<int, 5> x;
    

    Ohne die Standardbibliothek von C++0x kann man auch std::tr1::array oder boost::array einsetzen.

    std::array höre ich auch zum ersten Mal. Gibt es bei dieser Datenstruktur einen Vorteil gegenüber dem Vektor?


Anmelden zum Antworten