# C++



## Betagurke (4. März 2012)

Guten Tag, 

ich versuche mich im Moment immer noch an der Programmierung mit C++, nun habe ich eine Frage: 

Ich habe folgendes aus dem Tutorial abgetippt und danach kompiliert.



/*  

   main.cpp  

*/  
#include <iostream>  

using namespace std;  

int main()  
{  

    int a,b; 

    cout << "Bitte geben Sie bitte eine Zahl ein:" << endl;

    cin >> a; 

    cout << endl << "Gitte geben Sie bitte nochmal eine Zahl ein:" << endl;

    cin >> b; 

    if (a == b) 
    { 
        cout << "Beide Zahlen sind gleich"; 
    } 

    if (a < b) 
        cout << "a ist kleiner als b"; 


    //Wenn die Anweisung in der Klammer nur eine Anweisung umfasst, dann kann man die Klammern weglassen
    if (a > b) 
        cout << "b ist kleiner als a"; 

    return 0;  
} 

Nun dann hat sich die Anwendung geöffnet mit der Meldung "Bitte geben sie eine Zahl ein", ich habe die 7 gewählt, dann kam die Meldung: "Bitte gebe sie die Zahl nochmal ein", ich habe folglich wieder die 7 eingegeben, doch das Fenster hat sich nach Eingabe der 2 Zahl einfach geschlossen, dieses Problem habe ich sehr oft und ich weiß einfach nicht mehr weiter, ich hoffe ihr könnt mir da helfen. 

Nebenfrage: Kennt ihr gutes Tutorial zu C++ (kostenlos, da mit im Moment das Geld für ein gutes Buch fehlt und ich denke, dass für die Grundlagen auch ein Tutorial reicht)? Ich arbeite im Moment mit diesem: Online-tutorials.net - C++ Tutorial Teil 1

Vielen Dank im Voraus, Betagurke


----------



## AMD (4. März 2012)

Mach einfach mal eine Zeile über dem "return 0" das hier:

```
system("PAUSE");
```


----------



## Betagurke (4. März 2012)

Vielen Dank es hat funktioniert.


----------



## Robonator (4. März 2012)

Vieleicht offtopic aber: Krass wie sehr sich C++ von C# unterscheidet


----------



## hardware_fanatiker (4. März 2012)

Wobei System seht teuer ist, da würd ich, bevor man sichs angewöhnt, eher sachen nehmen wie getch(), dafür musste nur noch eben conio.h einbinden.


----------



## AMD (4. März 2012)

Schon möglich, aber da es hier nur drum geht 2 Zahlen zu vergleichen, sollte das doch ziemlich egal sein ^^


----------



## Mashed (4. März 2012)

Wie wäre es mit

```
cout << "Press return to exit" << endl;
while(cin.get() != '\n');
```
?
Ist im Gegensatz zu den vorigen beiden Vorschlägen standardkonform und plattformunabhängig.


----------



## Skysnake (4. März 2012)

Ja das geht und ist standardkonfrom und plattformunabhängig. 

Kann man durchaus so machen, oder einfach linux nutzen, dann brauch man so was nicht 

PS: wenn man das Programm unter windows aus der shell startet, braucht man das glaub ich auch nicht.


----------



## dot (4. März 2012)

Oder halt mit "cin" auf eine Eingabe warten. Problem tritt wirklich nur auf, wenn man eine Entwicklungsumgebung nutzt und daraus das Programm startet.


----------



## Betagurke (4. März 2012)

danke für die vielen Antworten, ich benutzen die von Mashed mit einer eränderten Meldung. 
Nun habe ich aber noch eine Frage, was bedeutet diese "endl" bzw. was macht es?


----------



## AMD (4. März 2012)

endl = EndLine
Dadurch springst du in der Konsole in die nächste Zeile.


----------



## Betagurke (4. März 2012)

danke..


----------



## Skysnake (4. März 2012)

endl 

ist ein Funktionsaufruf, der dafür sorgt, das der buffer geleert und auf die Console ausgegeben wird. zusätzlich wird eine neue Zeile angefangen.

Relevant ist eigentlich nur das ein Zeilenumbruch erfolgt. Also quasi ein \n beim print().

endl kann man sich auch als endline merken


----------



## Betagurke (4. März 2012)

danke, nun bin ich im Tutorial weiter und habe verschiedene Programme verändert, dies ist aber 1:1 abgetippt, und der Compiler zeigt mir bei "return 0;" ständig einen Fehler an, warum? 
Meiner Meinung nach ist alles richtig.. 
#include <iostream>

using namespace std;

int main ()
{

    int i = 0;

    cout << "Bitte geben Sie eine Zahl ein: " << endl;

    cin >> i;

    //Die "if-Variante"

    if (i == 0)
       cout << "Null";
    else if(i == 1)
         cout << "Eins";
    else if(i ==  2)
         cout << "Zwei";

    else
        cout << "Die Zahl ist groesser als zwei";

//Die "Swicht-Variante"

switch(i)
{
         case 0:
              cout << "Null";
              break; 

         case 1: 
              cout << "Eins";
              break;
         case 2:
              cout << "Zwei";
              break;

         default:
             cout << "Die Zahl ist groesser als zwei";
             break;

while(cin.get() != '\n');
}
return 0;


----------



## hardware_fanatiker (4. März 2012)

Das return 0 muss in die geschweifte, die hinter dem int main aufgemacht wurden, wahrscheinlich kleiner Tipp-Fehler vom Turorial Schreiber.


----------



## Betagurke (4. März 2012)

also danke für deinen tipp, aber ich habe jetzt hinter das "return 0;" die geschweifte Klammer gemacht und es funktioniert trotzdem nicht?


----------



## Crysis nerd (4. März 2012)

Skysnake schrieb:


> endl
> 
> ist ein Funktionsaufruf, der dafür sorgt, das der buffer geleert und auf die Console ausgegeben wird. zusätzlich wird eine neue Zeile angefangen.
> 
> ...


 
Sry, dass ich klugscheiße, aber ich denke man sollte dich verbessern: Funktionsaufruf ist es ja wirklich nicht. Also nicht, dass wir unseren neuen Freund verwirren hier... 

betagurke: du musst auch alle geschweiften Klammern schließen, also auch die der switchanweisung.


----------



## AMD (4. März 2012)

Betagurke schrieb:


> also danke für deinen tipp, aber ich habe jetzt hinter das "return 0;" die geschweifte Klammer gemacht und es funktioniert trotzdem nicht?


 Nein, so hier:

```
return 0;
}
```


----------



## Betagurke (4. März 2012)

so hab ich es


----------



## M4jestix (4. März 2012)

Betagurke schrieb:


> so hab ich es



direkt vor dem "return 0;" muss ebenfalls eine schliessende geschweifte Klammer.... 
Wenn du das auch hast sollte es eigentlich gehn.


----------



## AMD (4. März 2012)

Ach stimmt, vom Switch Befehl.
Fehlermeldung posten wäre auch gut in Zukunft


----------



## M4jestix (4. März 2012)

AMD schrieb:


> Ach stimmt, vom Switch Befehl.
> Fehlermeldung posten wäre auch gut in Zukunft





@Betagurke: Welchen Compiler verwendest du denn eigentlich??


----------



## Skysnake (5. März 2012)

Crysis nerd schrieb:


> Sry, dass ich klugscheiße, aber ich denke man sollte dich verbessern: Funktionsaufruf ist es ja wirklich nicht. Also nicht, dass wir unseren neuen Freund verwirren hier...
> 
> betagurke: du musst auch alle geschweiften Klammern schließen, also auch die der switchanweisung.


 Was solls denn sonst sein? 

Kommt halt aus den Tiefen des iostream Header

Was das Ding am Ende wirklich GENAU macht, müsste man halt nachsehen, aber ich wüsste jetzt nicht, wie ich es sonst nennen soll, als nen Funktionsaufruf. 

Eigentlich steht da ja std::endl 

ARg. mom, ich seh was du meinst  Klar, für nen Funktionsaufruf, müsste endl() dastehen.... Also müsste es ein define sein, was man verwendet.


----------



## AMD (5. März 2012)

Wenn schon Klugscheißern, dann wenigstens richtig: endl ist ein (Stream-)Manipulator. Läuft letztendlich aber wieder eher auf eine Funktion hinaus.


----------



## Skysnake (5. März 2012)

Naja, aber ein "richtiger" Funktionsaufruf direkt ist es nicht, da die ja () haben. Also muss es ein Define sein.

Ich glaub ich muss echt mal in die Klasse rein schauen


----------



## AMD (5. März 2012)

Trotzdem kann man einen Manipulator eher mit einer Funktion als mit einem Define vergleichen.


----------



## Skysnake (5. März 2012)

Naja, da gabs ja aber vorher auch Kritik dran, als ich es als Funktion bezeichnet habe 

Was wenn man es GANZ genau nimmt ja auch zutrifft, da das endl an sich halt keine Funktion ist, auch wenn damit natürlich eine Funktion ausgeführt wird....

Irgendwie driftet das aber alles in Spitzfindigkeiten ab, die glaub ich eh keine Sau interessieren (inkl. mir )


----------



## Crysis nerd (5. März 2012)

Ja ich wollte es nicht erläeutern, weil wir den netten Betagurke dann nurnoch mehr verwirren 

Aber durch eure Kritik hab ich nochmal nachgeforscht, denn es ist DOCH anders als ich dachte.
Ich hatte angenommen:
endl ist irgendeine Konstante oder Makro, welches per die überladenen << operatoren in die cout klasse geschoben wird. Die Klasse verwendet dann diese Konstante, um etwas damit zu machen.
ABER, das scheint wohl nicht ganz richtig zu sein, denn es gibt zumindest eine Funktion, die tatsächlich endl() heißt:

```
_CRTIMP2_PURE inline basic_ostream<char, char_traits<char> >&
    __CLRCALL_OR_CDECL endl(basic_ostream<char, char_traits<char> >& _Ostr)
    {    // insert newline and flush byte stream
    _Ostr.put('\n');
    _Ostr.flush();
    return (_Ostr);
    }
```

Es ist tatsächlich so, dass das "endl" was wir nach einem cout schreiben ein Funktionspointer ist. Es gibt eine Variante des überladenen Operators <<, der Funktionspointer (in unserem Fall: "ios_base& ( *pf )(ios_base&)" ) akzeptiert. Und mit endl übergeben wir der überladenen Operator funktion den Funktionszeiger auf endl, welcher die Funktion endl dann auch aufruft.

Pff, schön kompliziert 
Danke übrigens, dass ihr nochmal gemeckert habt, hat mich schlauer gemacht (ist ernst gemeint  )

Falls noch jemand diskutieren möchte: Kommt mal in den ProgrammiererChannel (siehe meine Signatur)

mfg
Lukas


----------

