Tutorials - C++ Tutorial Teil 1

Sprachenübersicht/Programmierung/C / C++/ C#

C++ Tutorial Teil 1

Diese Seite wurde 273967 mal aufgerufen.

Dieser Artikel wurde in einem Wikiweb System geschrieben, das heißt, Sie können die Artikel jederzeit editieren, wenn Sie einen Fehler gefunden haben, oder etwas hinzufügen wollen.

Editieren Versionen Linkpartnerschaft Bottom Printversion

Keywords: C++ Tutorial, Einsteiger, C++ Kurs, Grundlagen, Programmieren, Programmiersprache, Objektorientiert, cout, stl, flush, Klassen, Ableitung, Polymorphie, if-statements, kontrollsturkturen, ansi c++, operator, const, unsigned

Abbildung

Inhaltsverzeichnis



Vorwort Top



Dieser Artikel ist ein Gemeinschaftstutorial von Online-tutorials.net, jeder kann es unter Editieren verbessern.

Um besser lernen zu können, solltest du alle Beispiele abtippen, und nicht kopieren, es wäre gut, wenn du dir, nachdem du etwas neues gelernt hast, darüber Gedanken machst, ob du dazu ein Beispiel schreiben kannst, und es als Vorschlag hier postest.

Wenn du fragen hast, kannst du sie gerne im Forum posten.

Wir haben übrigens geplant, aus diesem Tutorial eine Tutorialserie zu machen, die am Schluss eine ausführliche Einführung in DirectX macht. Als Krönung gibt es dann vielleicht am Ende ein kleines 3D-Spiel.

Warum dieses Tutorial geschrieben wurde/wird Top



Es gibt zwar tausende C++ Tutorials im Internet, aber ich habe noch kein einziges Tutorial gesehen, mit dem ich richtig zufrieden war, die meisten Tutorials, die ich kenne, halten sich nicht an den C98 Standard, und schaden mehr als sie bringen.

Ich werde alles daran setzen, dass sich dieses Tutorial an den C++ Standard hält.

Hilfe Top



Jeder der noch etwas verbessern oder ergänzen will, ist herzlich dazu eingeladen. Wenn du was verändert hast, kannst du dich unten als Autor mit deiner Veränderung eintragen, damit das die anderen Wissen Lachend

Software Top



Bevor's losgeht brauchst du noch einen Compiler bzw. eine IDE, hier solltest du etwas finden:

www.c-plusplus.de/compiler.htm

oder du kannst hier drei Monate lang Microsoft Visual C++ lang kostenlos testen.
Wenn du bereit bist etwas Geld auszugeben, so würde ich dir empfehlen, das Programm zu kaufen. Es ist zwar teuer, aber sein Geld wert, da es eine sehr gute IDE ( integrated development environment, englisch für integrierte Entwicklungsumgebung) ist.

Kapitel 1: Grundlagen Top



Ok, nachdem du die IDE gestartet hast, und ein neues Projekt angefangen hast, können wir anfangen:

Das erste Programm Top



Es ist eine Programmierer-Tradition, das man beim ersten Programm in einer neuen Programmiersprache immer ein Programm schreibt, das Hello World auf den Bildschirm ausgibt, das machen wir jetzt auch.

Gib also folgendes ein, kompilere und starte es dann:

Code:



#include <iostream>

using namespace std;

int main()
{
   cout << "Hello World";

   return 0;
}



Es sollte Hello World auf dem Bildschirm erscheinen, wenn nicht hast du ein Problem mit dem Compiler/der IDE, frag im C++ Forum wie man ihn bedient.

Unter Windows wird sich das Programm wahrscheinlich sofort wieder schließen, das kann man umgehen, indem man in die Kommandozeile (Start->Ausführen-> cmd eingeben) geht, dort zum Directory geht, und das Programm dann manuell startet.

Ansonsten kann man am Schluss, vor return 0; folgendes benutzen, das wird aber erst später erklärt:

Code:


cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin.get();



Ok, du hast es also geschafft, dein erstes Programm ;-)

Erklärung

Header Top



Code:


#include <iostream>
#include <cstdio>
#include <string>



#include sagt dem Programm, dass es Befehle aus der Datei zwischen den <> Klammern laden soll.

Anmerkung:


Bei STL Headern wird kein .h verwendet (#include <iostream>;#include <string>, und vor Standard-Header, die für C geschrieben wurden, wird ein c gesetzt, und ebenfalls kein .h verwendet. (#include <cstdio>



int main() sagt dem Compiler, dass das Programm hier anfängt, alles, was zwischen den {} Klammern steht, wird schrittweise durchgemacht. {} Klammern sind immer Anweisungsblöcke, alles was dazwischen steht, gehört zusammen.

Das Programm beginnt jetzt bei der { Klammer, und geht zu cout, cout gibt eine Zeichenkette aus.

Alles was zwischen den " " Zeichen ist, ist eine Zeichenkette, alles zwischen ' ' ist ein Buchstabe.

Jeder Befehl in C++ hat einen Strichpunkt ; am Schluss, dabei ist es egal ob der Befehl über mehrere Zeilen geht, solange keine Zeichenkette offen ist.

Jetzt sagen wir der Konsolenanwendung, dass das Programm ordnungsgemäß, ohne Probleme beendet wurde: return 0;

Die Klammer } schließt die main Funktion ab.

using namespace std; wird später erklärt, dazu brauchst du noch weiteres Wissen.

Das zweite Programm Top



Ich hoffe du hast die Erklärung vom letzten Programm verstanden, wenn nicht kannst du im Forum fragen.

Kommentare

Ok, nimm das erste Programm, und füge folgendes am Anfang hinzu:

Code:


//Mein zweites Programm 
    
/* 
    
   main.cpp 

*/ 



Das sind Kommentare, es gibt in C++ 2 verschiedene Varianten , Kommentare zu setzen.

Die erste Variante behandelt alles nach // bis zum Zeilenende als Kommentar, der vom Compiler einfach ignoriert wird.

Bei der 2. Variante wird alles zwischen /* und */ über mehrere Zeilen als Kommentar behandelt, und vom Compiler ignoriert.

Wenn du das Programm jetzt kompilierst, sollte das gleiche passieren wie beim letzen mal.

Steuerzeichen, cout, flush, ...

Tippe jetzt folgende Zeilen ab, und kopier sie zwischen die beiden {} Klammern, nach int main().

Code:


    cout << "Hi,\n";
    cout << "das hier ist mein 2. Programm," << " das Steuerzeichen,";
    cout << " Kommentare, und\nflush() erläutert." << endl << endl;
    cout.flush();



Das ganze sollte jetzt so aussehen:

Code:


//Mein zweites Programm 
    
/* 
    
   main.cpp 

*/ 

#include <iostream> 

using namespace std; 
    
int main() 

    cout << "Hi,\n";
    cout << "das hier ist mein 2. Programm," << " das Steuerzeichen,";
    cout << " Kommentare, und\nflush() erläutert." << endl << endl;
    cout.flush();

    return 0; 
}



Fertig kompiliert, und ausgeführt sollte es jetzt folgendes Ausgeben:

Hi,
das hier ist mein 2. Programm, das
Steuerzeichen, Kommentare, und
flush() erlaeutert.

Erklärung

Wie du hier siehst, kann man mit cout noch viel mehr machen, als im ersten Programm.

Man kann z.B. mehrere Strings (Zeichenketten) hintereinander ausgeben lassen:

Code:


cout << "Text1" << "Text2";



Ausgabe: Text1Text2

Dann kann man mit sogenannten Steuerzeichen verschiedene Sonderaktionen machen:

Code:


\n Macht einen Zeilenumbruch: New Line
\r Macht einen Wagenrücklauf (Return)
\a Signalton
\\ Macht ein Backslash (\)
\b Backspace, löscht das linke Zeichen
\f Formfeed, macht einen Seitenvorschub
\t Macht einen horizontalen Tabulator
\v Macht einen vertikalen Tabulator
\" Macht ein "
\' Macht ein '



Wenn man diese Zeichen in den Text einfügt, machen diese Zeichen ihre Aufgabe, so gibt z.B. cout << "Text\nText2"; folgendes aus:

Text
Text2

Obwohl es eigentlich 2 Zeichen sind, werden sie als eines gezählt.

Wie man ä`s,ö`s, und ü's macht erfahrt ihr
hier.

cout gibt den Text in einen Ausgabenbuffer, das ist einfach ein Stück Speicher, das reserviert wurde.

Der Ausgabebuffer wird normalerweise am Schluss geleert, aber manchmal kann der auch durcheinander kommen, und darum verwendet man cout.flush();

cout.flush(); macht einfach, dass alles was im Moment im Buffer ist ausgegeben wird.

So, jetzt bleibt nur noch endl, endl kann man zwischen diese << Output-Operatoren geben, als wär es ein String.

endl macht 2 Dinge:

1. \n
2. cout.flush();

d.h. Zuerst wird eine neue Zeile angefangen, und danach wird der String ausgegeben.

Variablen Top



Variablen sind Speicherteile, die einen Wert speichern können.

Man kann ihnen einfach einen Wert zuweisen, und wieder auslesen.

Bevor man eine Variable benutzen kann muss man sie initialisieren, um Fehlern vorzubeugen, und die richtige Größe benutzen zu können.

Schauen wir uns dazu ein Beispiel an:

Code:


/* 
    
   main.cpp 

*/ 

#include <iostream> 

using namespace std; 
    
int main() 

    int z;
    int i = 3;

    cout << "Der Wert der Variablen: " << i << "/" << z << endl;

    return 0; 
}



Ausgabe:
Der Wert der Variablen: 3/-858993460

Mit int z wird eine Variable im Speicher reserviert. int i = 3; reserviert die Variable mit dem Namen i und setzt sie auf 3.
Man kann diese Variable dann mit cout wie eine Zeichenkette ausgeben.

Wenn man mehrere Variablen vom gleichen Typ reservieren will, so kann man sie mit einem Beistrich nebeneinander schreiben:

//Reserviert i, z, Test, und y
int i,z,Test,y;

int ist der Variablentyp, es gibt folgende verschiedene:

int Eine ganze Zahl(ohne Komma), auf englisch Integer
char Ein Zeichenkette
bool Kann true oder false sein
float Eine Kommazahl
double Eine sehr große Kommazahl mit doppelt so viel stellen wie float
short Kleiner int
long Kann vor Variablen stehen, und vergrößert sie
signed Kann vor Variablen stehen, und erlaubt die Verwendung von positiven und negativen Zahlen
unsigned Erlaubt nur positive Zahlen, dadurch wird der Wertbereich größer

Du wirst im laufe der Zeit noch auf viele Variablentypen treffen, Tante Google wird dir sicher helfen, falls ein Typ unklar ist.

Anmerkung:


Ein Komma wird in C++ nicht wie ein Komma, sondern wie im Englischen mit einem Punkt gemacht.



Wenn eine Variable überschritten/unterschritten wird, fängt sie von vorne(dem Mindestwert)/vom Ende(höchstwert) wieder an.

Beispiel:

int i = 214748357;
cout << i;

Ausgabe: -2147483639

Dies nennt man overflow/underflow.

Achtung

Wenn man Variablen nicht initialisiert, haben sie je nach Compilereinstellungen 0, oder nicht, man sollte beim Programmieren bedenken, das sie beim Start nicht umbedingt 0 haben muss, und sie eventuell auf 0 setzen.

Um eine Variable einzulesen kann man cin benutzen.

Cin funktioniert ähnlich wie cout, nur das der Operator in die andere Richtung zeigt: >>

Code:


/* 
    
   main.cpp 

*/ 

#include <iostream> 

using namespace std; 
    
int main() 

    int z;

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

    cin >> z;

    cout << "z hat den Wert: " << z << endl;

    return 0; 
}



Operatoren Top



Man kann Variablen auch manuell setzen dazu macht man folgendes (Zuweisungsoperator):

Code:


//Initialisiert MeineVariable mit dem Wert 4, ändert anschließend den Wert auf 3 und gibt den Wert der Variable aus.

int MeineVariable = 4;

MeineVariable = 3;

cout << MeineVariable << endl; //Ausgabe 3

//Die Folgende Zeile addiert zuerst MeineVariable & MeineVariable, setzt zuerst MeineZweiteVariable, und dann i auf das Ergebniss

i = MeineZweiteVariable = MeineVariable + MeineVariable;



Hier wird die Variable die rechts steht auf den rechten Wert gesetzt.

Mit bestimmten Operatoren kann man Variablen verändern, so kann man mit +,-,*,/ Variablen, oder Zahlen miteinander addieren/subtrahieren/multiplizieren, oder dividieren.

Hier gibt es wieder ein größeres Beispiel:

Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int main() 

    int z,x,y,Test;

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

    cin >> z;

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

    cin >> x;

    y = Test = ((z + x) * x) + 5;

    cout << "y hat den Wert: " << y << endl;

    return 0; 
}



Ausgabe:

Bitte geben Sie eine Zahl ein:
1

Bitte geben Sie eine zweite Zahl ein:
3
y hat den Wert: 17

Ein weiterer Operator ist der Modulo-Operator, er gibt den Rest einer ganzzahlen Division zurück;

int i = 7 % 3; // i ist 1 Rest (7/3 = 2 mal 1 Rest)

Es gibt noch einen Operator: sizeof. Er gibt die Größe der Variable in Bytes zurück.

Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int a;

int main() 

    cout << "int: " << sizeof(int) << endl;
    cout << "char: " << sizeof(char) << endl;
    cout << "double " << sizeof (double) << endl;
    cout << "a: " << a << endl;

    return 0; 
}



Man kann den Typ für sizeof eine Klammer benutzen, oder nicht.

Konstante Top



Gewisse Dinge, wie z.B die Zahl PI sind immer gleich groß.

Für diese Dinge gibt es Konstanten:

const float PI = 3.14159265358932;

Diese Variable kann später nicht mehr verändert werden.

Warum benuzt man Konstanten?

Einerseits weil man diese Variablen dann später nicht mehr versehentlich verändern kann, und andererseits machen sie das Programm viel besser lesbar, weil jemand, der den Code noch nie gesehen hat sofort weiß, das diese Variable immer gleich bleibt.

Es gibt 2 Arten von Konstanten: Runtime-Konstanten und Compiletime-Konstante. Runtime Konstante werden erst wärend der Ausführung des Programms erstellt, Compiletime werden beim compilen erstellt.


Hier ein paar Beispiele:

Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int main() 

    int a = 5;

    const int c = 5;    //Compiletime Konstante
     const int x = 5*7;    //Compiletime Konstante

    int d = 0;
    cin >> d;

    const e = d;        //Runtime Konstante


    const int b = a;    //a könnte theoretisch während der Laufzeit geändert werden
                        //Runtime Konstante
    
    int const z;        //Noch was, man kann const auch nach dem Variablentyp schreiben

    return 0; 
}



Namensvergabe Top



Für die Benennung der Variablen gibt es einige Einschränkungen:

- Variablennamen dürfen nicht mit einer Zahl am Anfang beginnen: 1Test
- Variablennamen dürfen keine Leerzeichen in der Mitte haben: Test Test
- Variablennamen dürfen keine Sonderzeichen wie z.B. .;,"< oder + (verwende bis auf _ am besten keine Zeichen die nicht im Alphabet sind
- Variablen dürfen keine Namen von Funtionen aus den Bibliotheken haben
- Variablen dürfen nicht nach C++ Schlüsselwörter (if, case, class,...) benannt werden

Es gibt verschiedene Konventionen für die Namensvergabe für Variablen. Einige Leute schreiben zum Beispiel jedes Wort in einer Variable groß: IchSpeichereEtwas, FileName. Andere schlagen vor zwischen jeder Variable einen _ zu machen.

Besonders beliebt ist die ungarische Notation, die vor Zeiger ein p, vor Funktionen ein fn, vor Handles ein h usw. setzt.
Es ist egal falls du nicht weißt was das ist, dazu kommen wir später. Die ungarische Notation ist für C++ aber auch sehr umstritten, unter anderem, weil man eigene Typen erstellen kann.

Gültigkeitsbereiche Top



Es gibt verschiedene Gültigkeitsbereiche, von denen es wiederum 2 Arten gibt:

- lokale Gültigkeitsbereiche, sie sind zwischen den { } Klammern
- globaler Gültigkeitsbereiche, er ist im gesamten Programm gültig

Globaler Gültigkeitsbereiche:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int a;

//Lokaler Gültigkeitsbereich von Main
int main() 

    
    int b;

    a    = 33;
    b    = 3;


    //Gültigkeitsbereich - Erste Unterebene von main
    {
        int c;

        a    = 3343;
        b    = 45;
        c    = 3;

        //Gültigkeitsbereich - Unterebene von der ersten Unterebene von main
        {
            int d;

            a    = 3343;
            b    = 45;
            c    = 3;
            d    = 343;
        }
        //2. Unterebene Ende

        //d ist nicht mehr gültig
    }

    //1. Unterebene Ende

    c = 3;    //Fehler c ist nicht mehr gültig
            //d ist nich mehr gültig

    //Gültigkeitsbereich - Zweite Unterebene von main
    {
        
        //Hier ist nur a und b gültig
    }

    return 0; 
}
//Lokaler Gültigkeitsbereich von main Ende



Wenn wir die Struktur anschauen:

Struktur:


- Globaler Gültigkeitsbereich
    - Gültigkeitsbereich von Main
        - Erste Unterebene von Main
            - Unterebene der ersten Unterebene von Main
        - Gültigkeitsbereich der zweiten Unterebene von Main



Eine Variable immer in dem Gültigkeitsbereich in dem sie reserviert wurde, und in den Unterebene dieses Gültigkeitsbereichs (Verschachtelung) gültig

Man kann zwei Variablen mit dem gleichen Namen reservieren, einmal im lokalen, und einmal im globalen Gültigkeitsbereich, innerhalb des lokalen Gültigkeitsbereiche wird dann immer die lokale Variable benutzt, sonst die globale.

Globaler Gültigkeitsbereiche:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int a = 3;

//Gültigkeitsbereiche von main
int main() 

    {

    int a = 55;

    cout << a << endl;    //Gibt 55 aus

        }

    {    // überdeckt die lokale wieder d.h. a == 55 ist nur innerhalb eines Gültigkeitsbereichs
        cout << a << endl;    //Gibt 3 aus
    }

    return 0; 
}



Kontrollstrukturen Top



Um das Programm flexibler zu machen benötigen wir Kontrollstrukturen. Damit kann man Variablen überprüfen.

Eine Möglichkeit ist mit if/else.

Mit if (Variable) überprüfen wir, ob die Variable true/1 (Wahr), oder false/0 (Falsch) zurückgibt. Wenn es wahr ist, wird das in den { } Klammern ausgeführt.


Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int main() 

    
    int a,b;

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

    cin >> a;

    cout << endl << "Bitte geben Sie 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; 
}



Wie wir hier sehen gibt es in C++ Vergleichsoperatoren, sie vergleichen 2 Variablen, und geben true oder false zurück.

Vergleichsoperatoren:

== ist gleich
!= ungleich
< kleiner als
> größer als
<= kleiner oder gleich
>= größer oder gleich

Wichtig:


In einigen anderen Programmiersprachen vergleicht man nicht mit == sondern mit =, in C++ weist = einer Variable einen Wert zu, und gibt dann true zurück.

int a = 5;

if (a = 3)
{
    cout << "test";
}

Gibt IMMER test aus, und setzt a auf 3!




Es gibt ausserdem noch else und ifelse, wenn man if benützt, kann man ifelse (Ansonsten wenn) und else benutzen:

Code:


/* 
    
   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 << "Bitte geben Sie bitte nochmal eine Zahl ein:" << endl;

    cin >> b;

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

    //Wenn if oben false ist überprüfe ob a kleiner als b ist
    else if (a < b)
    {
        cout << "a ist kleiner als b";
    }
    //Ansonsten gib b ist kleiner als a aus
    else
    {
        cout << "b ist kleiner als a";
    }

    if (a = 3)
        cout << endl << endl << "Das hier beweist, dass = einen Wert zuweist, und immer true zurückliefert." << endl;

    if (a != b)
        cout << endl << a << " ist nicht " << b << endl;

    //Wie in der Mathematik kann man beliebig Klammern setzen, das UND dreht das Ergebnis um (true wird zu false und false zu true)
    if (!(a != b))
        cout << endl << a << " ist " << b << endl;

    //0 ist das gleiche wie false, alles andere ausser 0 ist true
    if ((a == b) == 0)
        cout << endl << a << " ist nicht" << b << endl;

    return 0; 



Wie in einem Beispiel weiter oben angedeutet kann man, wenn zwischen den { } Klammern nur eine Anweisung ist, die Klammern weglassen.

Jetzt fehlt uns nur noch das UND (&&), und das ODER (||).

Code:


if (a == b && a == 3)
    cout << " a und b haben den Wert 3." << endl;

if (a == 4 || a == 3)
    cout << " a hat den Wert 3 oder 4." << endl;



Der Ausdruck wird in C++ nur soweit ausgewertet, bis das Ergebnis feststellt. Bei if (a == 4 || a == 3) wird nur (a == 4) ausgewertet (wenn (a == 4) true ist), und der Rest stehengelassen, da die erste Bedingung sowieso true zurück gibt.
Bei (a == b && a == 3) wird a == 3 nicht ausgewertet, wenn a == b false ergibt. Das nennt man Lazy Evaluation.

Switch Top



Wenn man eine bestimmte Variable oft überprüfen will, kann man auch switch verwenden. Dabei wird eine Variable (char oder int) überprüft:

Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int main() 

    //Reserviert die Variable i
    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 größer als zwei";

    //DIE SWITCH VARIANTE

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

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

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

        default:
            cout << "Die Zahl ist größer als zwei";
            break;
    }

    return 0; 
}



Dadurch wird der Code zwar größer, aber er ist besser zu lesen. Bei switch erstellt der Computer eine Sprungtabelle, was die Performance verbessert.

Mit switch(Variablenname) gibt man dem Compiler an, welche Variablen man benutzen will, case überprüft auf den Wert danach, und ab dem Doppelpunkt werden Befehle ausgeführt.
Break bestimmt, dass der case fertig ist.

Default ist das gleiche wie else bei den if-statements, es wird benutzt, wenn alle anderen Abfragen nicht passen.

Code:


    switch(i)
    {
        case 1:
        case 2:
        case 3:
            cout << "gültig";
            break;
        default:
            cout << "Bitte geben Sie eine gültige Zahl zwischen 1 und 3 ein.";
                           break;
    }



Bei diesem Beispiel, wird das case nicht sofort mit einem break beendet, d.h. wenn i 1 ist, geht es so weit, bis break kommt.
Dadurch spart man sich viel Code.

Schleifen Top



Schleifen sind dazu da, bestimmte Vorgänge wiederholen zu lassen. Wenn wir z.B. eine Zins-Rechnung machen, dann können wir das Programm solange wiederholen, bis der Anwender 0 eingibt.

Die while Schleife Top



while(bool) wiederholt alles zwischen den {} (kann man wie üblich weglassen, wenn nur ein Befehl kommt), solange wie die Variable true ist.

Hier ein Beispiel:

Code:


/* 
    
   main.cpp 

*/ 
#include <iostream> 

using namespace std; 

int main() 

    int iLoop = 1;

    // Wenn iLoop false (0) ist, dann macht die Schleife nach dem Durchgang (falls im Moment einer läuft) nicht mehr weiter.
    while(iLoop)
    {
        cout << "Geben Sie bitte eine Zahl ein (0=Quit) ";
        cin >> iLoop;

        if(!iLoop)    //Mit ! dreht man das Ergebnis um, wenn iLoop false (0) ist, dann wird true daraus, und wenn es true ist, wird false(0) daraus.
            cout << endl << "cya" << endl << endl;
        else
            cout << endl << iLoop << "+2 ist " << iLoop +2 << endl;
    }

    return 0; 
}



Ausgabe:

Geben Sie bitte eine Zahl ein (0=Quit) 43

43+2 ist 45
Geben Sie bitte eine Zahl ein (0=Quit) 2

2+2 ist 4
Geben Sie bitte eine Zahl ein (0=Quit) 5

5+2 ist 7
Geben Sie bitte eine Zahl ein (0=Quit) 0

Die do while Schleife

Bei einer normalen while Schleife kann es sein, dass die Schleife kein einziges mal durchläuft, wenn von Anfang an false übergeben wird. Die do while Schleife führt den Inhalt der Schleife aber auf jeden Fall einmal aus. Wenn der Wert danach false ist bricht sie ab, ansonsten macht sie weiter.

Um sie zu benutzen muss man anstelle von while ein do schreiben, und das while(...) ganz am Schluss setzen.

Beispiel:

Code:


/* 

main.cpp 

*/ 
#include <iostream>

using namespace std;

int main() 

   bool bLoop = false;  //Eine boolsche Variable, sie kann entweder false (0) oder true(!0) sein

   do 
   { 
      cout << "Beenden mit 0"; 
      cin >> static_cast<bool> (bLoop);    //Wandelt die Variable von cin in eine boolsche Variable um
   } 
   while(bLoop); 

   return 0;



Ich weiß, das ist ein billiges Beispiel, aber im Moment fällt mir nichts besseres ein tongue

Aber welche Variante ist am besten? Keine, denn das kommt ganz darauf an, was wir machen wollen. Meistens benötigt man die while Schleife, aber manchmal ist man froh darüber, dass es die do while Schleife gibt.

Die for Schleife Top



Eine weitere, und vermutlich die am meisten benutzte Schleife, ist die for-Schleife.

Wenn man etwas ziemlich oft machen will, z.B. etwas berechnen, und dabei noch eine Variable, die sich bei jedem Durchgang erhöht brauchen kann, dann ist die for-Schleife optimal dafür geeignet.

Nehmen wir an, wir wollen eine Zahl potenzieren. Dann multiplizieren wir die Basis einige Durchläufe mit sich selbst.

Hier der Code dazu:

Code:


#include <iostream>

using namespace std;

int main()
{
    int iBase,n        = 0;
    int iCalculate  = 1;

    cout << "Geben sie eine Zahl ein:\n";
    cin >> iBase;

    cout << "\nWie oft wollen Sie sie mit sich selbst multiplizieren?:\n";
    cin >> n;

    //Läuft insgesammt n mal durch
    for(int i=0; i < n; i=i+1)
    {
        iCalculate = iCalculate * iBase;
    }

    cout << "\n\n" << iBase << " hoch " << n << " = " << iCalculate << "\n\n";

    return 0;
}



Die for Schleife besteht aus 3 Teilen:

for(Initialisierung;Bedingung;Statement)

Bei der Initialisierung wird eine Variable (meist die Laufvariable) initialisiert, man kann direkt Variablentyp Variablenname = 0; hineinschreiben, ohne das man die Variable vorher angelegt hat (z.B. mit int Variablenname)
(Manche Compiler zerstören die Variable nach der if Schleife, andere erhalten sie noch), man kann aber auch eine bestehende Variable benutzten for(i=0;i<20;i=i+1), oder for(;i<20;i=i+1) (hier wird i am Anfang nicht auf 0 gesetzt)

Die Bedingung kann entweder true oder false erhalten, und wird vor jedem Durchgang überprüft, wenn sie false ist wird die Schleife abgebrochen, und der nächste Durchgang nicht mehr gemacht.

Als 3. kann man eine Statement angeben, das bei jeden Schleifendurchgang gemacht wird, üblicherweise erhöht man hier die Laufvariable.

Man kann diese Teile jederzeit auslassen, so kann man z.B for(;bTest == falselaugh schreiben (das entspricht einer while Schleife)

Anmerkung:


Als C++ Programmierer fängt man beim Zählen nicht bei 1, sondern bei 0 an, und hört eine Zahl früher auf.

Das sollte man sich angewöhnen, damit man später weniger Probleme hat.



Übrigens kann man z.B. in der Bedingung mehrere Bedingungen angeben, die dann mit einem , getrennt werden.

z.B:

Code:


for(int i = 0, j = 50; i < 30, j > 30; i++, j--)
   std::cout << j << std::endl;



Inkrement, Dekrement, Präfix- und Postfixoperatoren Top



Mit den Inkrement- und Dekrementoperatoren kann man Variablen um 1 erhöhen, oder verringern,

Code:


int i = 0;
int j = 0;

//Statt
i = i + 1;
j = j - 1;

            //kann man auch folgendes schreiben:
i++;j--;    //schreiben 
            //es ist übrigens egal ob die beiden Befehle in einer Zeile sind,
            //der ; trennt sie



i++; <- ++ wird Inkrementoperator genannt, und erhöht den Wert der Variable um 1.
j--; <- -- wird Dekrementoperator genannt, und verringert den Wert der Variable um 1.


Diese Methode erspart übrigens nicht nur Tipparbeit, sondern ist auf älteren Prozessoren (bis zur Pentium-Klasse) auch schneller , allerdings spielt das heute fast keine Rolle mehr.

Bei einer for Schleife schaut's meistens übrigens so aus:

Code:


for(int i = 0;i < iAnzahlderElemente;i++)
{
}



Es gibt auch noch den Präfix, und den Postfixoperator, sie machen eigentlich das gleiche wie die oben genannten Operatoren, bis auf einen kleinen Unterschied.

Codebeispiel:



int i = 0;
int j = 0;
int k = 0;

i = j++;    //Hier wird i zuerst den Wert von j zugewiesen, und j dann um 1 erhöht
        
//i ist 0

i = ++k;    //Hier wird zuerst k um 1 erhöht, und dann bekommt i den Wert von k

//i = 1



Jetzt werden einige sicher an den Namen von C++ denken. laugh

Casten Top



Manchmal ist es notwendig einen Variablentyp umzuwandeln, wenn man einen Fließkommawert hat, aber eine ganze Zahl hat, muss man den float in einen int umwandeln.

Dies kann man mit GecasteteVariable = static_cast<Variablentyp> (Variable); machen.

Hier ein Beispiel:

Code:


float    fTest = 21.2321321f;
int        iTest = static_cast<int> (fTest);    //Wenn man static_cast<int> nicht machen würde, würde der Compiler hier eine Warnung ausgeben, in anderen Fällen können Fehler entstehen



Es gibt noch 2 weitere Arten, die aus C übernommen wurden, und veraltet sind, mit denen man aber casten kann:

Code:


float    fTest = 21.2321321f;

int a = (int) fTest;    //c style cast
int a = int (fTest);    //function style cast



Merken:


C-Casts sind böse, C++ casts sind gut. C-Casts sagen nichts, wenn man sie falsch benutzt, C++ casts geben Fehlermeldungen aus 



Hier gibt es noch ein schönes Tutorial zu dem Thema: In C++ richtig casten

Ein weiteres Beispiel:

In C++ gibt es den Variablentyp char, dieser Typ hat immer 1 Byte, also 256
verschiedene Möglichkeiten, und kann den
ASCII Code darstellen.
Wenn wir diese Variable in einen int umwandeln, bekommen wir die Nummer des
Codes.

Die ersten Zeichen sind übrigens Steuerzeichen (Wagenrücklauf...), und
werden deshalb nicht korrekt dargestellt.

Code:


#include <iostream>

using namespace std;

int main()
{
cout << "Der ASCII Code:\n";

//Eine Schleife die 256 (von 0 bis 255) mal durchläuft
for(int i = 0; i < 255;i++)
//Gibt die Zahl, und den umgewandelten char aus
cout << "\n" << i << ": " << static_cast<char>(i);

return 0;
}



Weitere Operatoren Top



Bitoperatoren

[FEHLT]

Erweiterte Zuweisungsoperatoren

Damit man nicht immer i = i + 40; schreiben muss kann man stattdessen

i +=40;

verwenden.

Code:



int i = 1;

i += 20; // das selbe wie i = i + 20;

cout << i << endl;    //Ausgabe 21



Das selbe geht mit den anderen arithmetischen Operatoren:

i -= 20;
i *= 20;
i /= 20;
i % 20;

Arrays/Felder Top



Angenommen wir haben einige Zahlen, z.B. die Lebenspunkte der Gegner in einem Spiel. Jetzt haben wir eine größere Anzahl an Daten, die wir einzeln in Variablen speichern müssen:

100 //Lebenspunkte
53
34
95
100
232

//Diese Elemente nennt man Felder


In C++ kann man das mit Arrays umsetzen, das Programm reserviert einfach eine Reihe Variablen hintereinander.


Mit

Variablentyp Variablenname[AnzahlderFelder];
int iTest[30];

oder

Variablentyp Variablenname[AnzahlderFelder] = { Feld1, Feld2, ...}; //Hier kann man die Felder nacheinander setzen (man muss nicht allen einen Wert geben)
int iTest[5] = {1,2,99}; // Die ersten 3 erhalten den Wert links, der Rest wird auf 0 gesetzt

Code:


#include <iostream>

using namespace std;

int main()
{
    //Reserviert nacheinander 6 int Variablen für die Lebenspunkte 
    int iHealthpoints[] = {100,53,34,95,100,232};
    int iEnemy            = 0;


    cout << "Von welchem Gegner wollen Sie die Anzahl Lebenspunkte wissen (0-5)? ";
    cin >> iEnemy;

    if((iEnemy > 5) || (iEnemy < 0))
    {
        cout << "\nDer Gegner ist nicht vorhanden.";
    }
    else
    {
        cout << "\nDer NPC " << iEnemy <<  " hat " << iHealthpoints[iEnemy] << " Lebenspunkte." << endl;
    
        iHealthpoints[0] = 3;    //Die erste Stelle wird verändert
                                //In C++ fängt man bei 0 an zu zählen

        //iHealthpoints[6]        //Das Programm würde hier mit einem Fehler abbrechen, weil nur ein eindimensionales Feld von 0 bis 5 (insgesammt 6 Felder) erzeugt wurde
    }

    cout << "\nDer Array iHealthpoints braucht "<< sizeof(iHealthpoints) / sizeof(iHealthpoints[0]) << " Bit";

    cout << endl;

    //Legt einen Array an, ohne den Elementen einen Wert zu geben
    int iTestArray[3];

    //Setzt die Werte
    iTestArray[0] = 3;
    iTestArray[1] = 434;
    iTestArray[2] = 2;

    int iTestArray2[3];

    //iTestArray2 = {100,53,34,95,100,232}; <-- Fehler mit {} kann man nur beim reservieren zuweisen

   int iTestArray3[100] = {0};    //Setzt den Wert aller Elemente auf 0
   int iTestArray4[100] = {1};    //Setzt den Wert aller Elemente auf 0, nur das erste auf 1
   int iTestArray5[3]    = {0,1};//iTestArray5[0] ist 0, iTestArray5[1] ist 1, iTestArray5[2] ist 0

    cout << endl;

    return 0;    //Main wird beendet, und 0 gibt zurück, dass das Programm erfolgreich ausgeführt wurde
}



Wichtig:


Wie gesagt fängt man in C++ mit 0 an, der typische Anfängerfehler ist, das man einen Array mit z.B. 5 Feldern reservieren, und dann Variablenname[5] = 3; macht. Da man mit [0] anfängt ist bei [4] Schluss:

int i[5]; //Erzeugt an Array mit 5 Elementen

i[0] = 3;
i[1] = 3;
i[2] = 3;
i[3] = 3;
i[4] = 3;
i[5] = 3;    //<- Falsch, das 6. Element gehört nicht zum Array



So, das reicht uns natürlich nicht, wir wollen wieder mal mehr. Nehmen wir an wir wollen auch noch die ID, und den max. Schaden haben.

Code:


[100][0][35]        //[Lebenspunkte],[ID],[Schaden]
[53 ][1][668]
[34 ][2][575]
[95 ][3][287]
[100][4][530]
[232][5][457]



Diesen mehrdimensionalen Array legen wir mit:

Code:


int iTestArray[6][3] =
{
    {100,    0,    35},      //Das Komma wird benötigt, weil innerhalb der {} 6 unterschiedliche Werte erwartet werden.
    {53,    1,    668},
    {34,    2,    575},
    {98,    3,    287},
    {100,    4,    530},
    {232,    5,    457},
};

cout << "Der letze Gegner macht " << iTestArray[5][2] << " Schaden" << endl;



Natürlich kann man das ganze auch so realisieren:


Code:


int iTestArray[6][3];

iTestArray[0][0]    = 100;
iTestArray[0][1]    = 0;
iTestArray[0][2]    = 35;

iTestArray[1][0]    = 53;
iTestArray[1][1]    = 1;
iTestArray[1][2]    = 668;

iTestArray[2][0]    = 34;
iTestArray[2][1]    = 2;
iTestArray[2][2]    = 575;

iTestArray[3][0]    = 98;
iTestArray[3][1]    = 3;
iTestArray[3][2]    = 287;

iTestArray[4][0]    = 100;
iTestArray[4][1]    = 4;
iTestArray[4][2]    = 530;

iTestArray[5][0]    = 232;
iTestArray[5][1]    = 5;
iTestArray[5][2]    = 475;

cout << "Der letze Gegner macht " << iTestArray[5][2] << " Schaden" << endl;



Funktionen Top



Wenn wir ein Programm schreiben wollen, das an 10 verschiedenen Stellen den arithmetischen Mittelwert von 2 Zahlen berechnen, und ausgeben soll.
Jetzt können wir den Code, der den Durchschnitt berechnet natürlich 10 mal kopieren, aber wenn wir einen Fehler in dem Code finden müssen wir das 10 mal ändern.

Zehn mal ist noch kein Problem, aber was ist wenn wir das hundert bis tausend mal machen wollen (Ich weiß man berechnet normalerweise nicht an hundert verschiedenen Stellen den Mittelwert, aber es gibt auch noch andere Sachen, die man öfter wiederholen könnte laugh ).

Für sowas gibt es Funktionen, mit ihnen kann man das Programm in Module einteilen, die dann eigenständig Arbeiten.

Hier unser Programm ohne Funktion:

Code:


#include <iostream>

using namespace std;

int main()
{
    int iFirst = 3;
    int iSecond = 99;

    int iAverage = (iFirst + iSecond) / 2;

    cout << iAverage;

    //[..]
    
    iFirst = 5;
    iSecond = 88;

    iAverage = (iFirst + iSecond) / 2;

    cout << iAverage;

    return 0;
}



Und hier das Programm der Funktion (Function):

Code:


#include <iostream>

using namespace std;

//Deklariert vom Funktionsprototyp
int Average(int iFirst, int iSecond);

int main()
{
    cout << Average(3,99) << endl;

    //[..]

    cout << Average(5,88) << endl;

    return 0;
}

//Definition
int Average(int iFirst, int iSecond)
{
    //Zählt beide Zahlen zusammen, und dividiert sie anschließend durch 2
    int iAverage = (iFirst + iSecond) / 2;

    //Gibt den Wert der Variable zurück
    return iAverage;
}



Ein Prototyp einer Funktion schaut immer so aus:

RückgabeTyp Funktionsname(AnzahlDerParameterVon0BisBeliebig);

Damit sagen wir dem Programm das weiter unten eine Funktion definiert wird.

Die Funktion int Average(int iFirst, int iSecond);

wird nachdem sie Aufgerufen wird den Typ (RückgabeTyp, in diesem Fall int) zurückgeben (wenn nichts zurückgegeben wird, dann benutzt man void), und man muss dieser Funktion 2 Parameter (Variablen) übergeben, in diesem Fall 2 int's.

Bei der Definition wird der Prototyp nochmal angeschrieben, und zusätzlich kommt noch das, was die Funktion macht dazu.

Die Parameter int iFirst, int iSecond werden der Funktion beim Aufrufen übergeben, und sind dann innerhalb der Funktion gültig.

Am Schluss wird dann mit return Wert; der Wert der Funktion zurückgegeben, solange der Rückgabewert nicht void ist.

Ein 2. Beispiel:

Code:


#include <iostream>

using namespace std;

//Deklariert vom Funktionsprototyp
void GiveMessageOut(int iFirst);

int main()
{
    int i = 0;

    cout << "Geben Sie bitte eine Zahl ein: ";
    cin >> i;

    GiveMessageOut(i);

    return 0;
}

//Definition
void GiveMessageOut(int iFirst)
{
    cout << endl << "Der Wert, der dieser Funktion übergeben wird beträgt " << iFirst << endl;
}



main() ist übrigens die einzige int Funktion, die keinen Wert zurückgeben muss. (Sie gibt Standardmässig 0 zurück)

Globale Variablen Top



In Funktionen gelten globale Variablen wie im Abschnitt [jump=space]Gültigkeitsbereiche[/jump].

Beispiel:

Code:


#include <iostream>

using namespace std;

int i = 3;

//Deklariert vom Funktionsprototyp
void GiveMessageOut();

//Deklariert vom Funktionsprototyp

void GiveMessageOut2(int i);

int main()
{
    int iTest;

    cout << "Geben Sie bitte eine Zahl ein: ";
    cin >> iTest;

    GiveMessageOut();
    GiveMessageOut2(iTest);

    return 0;
}

//Definition
void GiveMessageOut()
{
    cout << endl << "Der Wert, der dieser Funktion übergeben wird beträgt " << i << endl;
}

//Definition
void GiveMessageOut2(int i)
{
    cout << endl << "Der Wert, der dieser Funktion übergeben wird beträgt " << i << endl;
}



Hier würde die 1. Methode (Funktion) 3 ausgeben, die 2. aber den Wert von iTest, da die lokale Variable immer Vorrang hat. Eine globale Variable wie in der ersten Funktion, GiveMessageOut() sollte man vermeiden, die zweite Version ist viel eleganter.

Funktionen überladen Top



Es kommt relativ häufig vor, das man für Funktionen verschiedene Datentypen als Parameter braucht.

Man könnte z.B. eine Funktion machen, die entweder void(nichts) und eine die einen int als Parameter erwartet.

Dank Vererbung können beide gleich heißen, je nachdem was übergeben wird sucht sich der Compiler die Richtige aus:

Code:


#include <iostream>

void Initialisiere();
void Initialisiere(int iStartValue);

int iVariable = 0;

int main()
{
   Initialisiere();

    //Gibt "iVariable hat den Wert:3" aus
   std::cout << "iVariable hat den Wert:" << iVariable << std::endl;

   Initialisiere(5);

    //Gibt "iVariable hat den Wert:5" aus
   std::cout << "iVariable hat den Wert:" << iVariable << std::endl;

   return 0;
}

void Initialisiere()
{
    iVariable = 3;
}

void Initialisiere(int iStartValue)
{
    iVariable = iStartValue;
}



Weiter Beispiele:

Code:


void Ausgabe();
int Ausgabe(int iVariable);
void Ausgabe(int iVariable, int y);



Jetzt darf man allerding keine weiter Funktion mit 1 oder 2 Integer als Parameter deklarieren.

Funktionen einen Standardwert geben Top



Nehmen wir an das wir eine Funktion haben, die als letztes Parameter eine boolsche Variable hat (eine Variable vom Typ bool, d.h. sie kann entweder true oder false sein). Wenn die Variable true ist, wird etwas ausgegeben, ansonsten wird nichts ausgegeben:

Code:


int TestFunction(int iVariable1, int iVariable2, bool bOutput)
{
   int i = iVariable1 + iVariable2;

   if(bOutput) //Äquivalent zu (bOutput == true)
       std::cout << i << std::endl;

   return i;
}



Wenn wir diese Funktion jetzt aber öfter brauchen, und das Ergebnis aber so gut wie nie von der Funktion ausgeben lassen, müssten wir jedesmal TestFunction(23,23,false); schreiben.

In C++ haben wir die Möglichkeit das zu vermeiden indem wir der Variable bOutput einen Standardwert zuweisen:

Code:


int TestFunction(int iVariable1, int iVariable2, bool bOutput = false)
{
   int i = iVariable1 + iVariable2;

   if(bOutput) //Äquivalent zu (bOutput == true)
       std::cout << i << std::endl;

   return i;
}



Das "= false" heißt, das der Compiler die Variable automatisch auf false setzt, wenn das letzte Parameter nicht angegeben wird.

Man kann den Parameter von rechts nach links einen Standardparameter geben, man darf dabei aber keine Variable auslassen:

richtig:


int Test(int x, int y = 3, int z = 3);



falsch:


//Nur von rechts nach links, keine Variable darf ausgelassen werden
int Test(int x = 3, int y, int z = 34);



Wenn wir Prototypen definieren, dürfen wir das nur in den Prototypen machen, sonst gibt der Compiler einen Fehler aus:

Code:


#include <iostream>

void Test(int i, int z = 3);

int main()
{
   Test(3);
}

//Das Standardparameter wurde im Prototyp schon gesetzt
void Test(int i, int z)
{
  std::cout << "Hallo";
}



Parameter der Main Funktion Top



Über die Parameter der main Funktion kann man dem Programm per Kommandozeile Werte übergeben, du hast sicher schon einmal mit DOS/Unix gearbeiten, und Erfahrungen damit gemacht.

Damit wir über die Kommandozeile Werte übergeben können verwenden wir folgenden aufbau:

Code:


int main(int argc, char* argv[])
{
   return 0;
}



Die Namen der Parameter sind natürlich frei wählbar. Das erste Parameter enthält die Anzahl der übergebenen Parameter, das zweite ein Array von Zeichenketten.

Beispiel:


#include <iostream>

int main (int argc, char* argv[])
{
    std::cout << "Dem Programm wurden " << argc << " Parameter uebergeben." << std::endl << "Parameter:" << std::endl << std::endl;

   for(int i = 0; i < argc; i++)
   {
       std::cout << (i+1) << ": " << argv[i] << std::endl;
   }
}



Wenn wir das Programm jetzt per Kommandozeile starten:

Code:


./Programmname "hallo" "hallo3"



gibt das Programm folgendes aus:

Code:


Dem Programm wurden 3 Parameter uebergeben.
Parameter:

1: ./Testprogramm
2: hallo
3: hallo3



Rekursion Top



Eine rekursive Funktion ist eine Funktion, die sich selbst aufruft, das ist etwas, was man oft für sehr elegante Lösungen verwenden kann.

Nehmen wir an wir wollen die Fakultät (Fakultät von n = n!= (n-1)*(n-1) * ... * (1)) einer Zahl berechnen.

Eine Möglichkeit wäre eine Schleife durchzugehen, und eine Variable immer wieder multiplizieren, wir verwenden in diesem Beispiel aber eine rekursive Funktion:

Code:


#include <iostream> 

//Prototyp
int Factorial(int iNumber);

int main (int argc, char* argv[]) 
{
    std::cout << "Die Fakultaet von 5 ist: " << Factorial(5) << std::endl;
  
    return 0;
}

//Diese Funktion ruft sich solange selbst auf bis iNumber-x 0 ist
int Factorial(int iNumber)
{
   if(iNumber > 1)   return iNumber * Factorial(iNumber -1);
   return iNumber;
}



Eine Funktion kann sich übrigens nur eine bestimmte Anzahl mal rekursiv selbst aufrufen, da es sonst negative Folgen auf die Hardware des Computers hätte.

Zeiger Top


Zeiger sind eine Eigenart die nur wenige Programmiersprachen besitzen. Dennoch sind sie ein fundamentales Prinzip in C sowie in C++. Um Zeiger verstehen zu koennen sollte man sich folgende frage stellen: Ich habe eine variable vom Typ int und kann ihr etwas zuweisen, aber an welcher Stelle im Speicher passiert nun etwas?

Code:


int m_integer = 1;


Irgendwie muss nun hinter dem Namen m_integer etwas Speicher sein, damit der Wert '1' an diese Stelle geschrieben werden kann. Dazu kann man sich nun die Adresse anschauen wo die '1' nun tatsaechlich steht. Das geht mit dem '&'-operator. Z.B.:

Code:


int m_integer = 1;
std::cout << "Integer Wert: " << m_integer
          << " Speicherstelle: " << &m_integer << std::endl;


Die Ausgabe sollte in etwas so aussehen:

Code:


 @pc:/tmp/>> Integer Wert: 1 Speicherstelle: 0x7fff5e2fc3ac


Nun wissen wir, dass jeder Variable einen Wert und eine Speicherstelle hat an der ihr Wert steht. Nun kann man sich einen zeiger auf Speicherstellen deklarieren durch ein '*' vor dem Variablennamen:

Code:


int *m_zeiger;



Hier haben wir soeben einen Zeiger auf einen Integerwert deklariert. Da wir noch nicht wissen auf welche Speicherstelle er zeigt interessiert uns der Inhalt eher weniger. Wir wollen erstmal den Zeiger auf etwas zeigen lassen was wir schon kennen:

Code:


int m_integer=1;
int *m_zeiger;

// zeige auf die speicherstelle von m_integer
m_zeiger = &m_integer;


Nicht vergessen, der &-operator gibt uns eine speicherstelle, und ein zeiger zeigt auf eben diese. Wenn wir nun wissen wollen worauf ein Zeiger denn nun wirklich zeigt koennen wir diesen 'dereferenzieren', das ganze geht mit dem *-operator:

Code:


int m_integer=1;
int *m_zeiger;
//gib integer erst aus:

std::cout << "Integer Wert: " << m_integer
          << " Speicherstelle: " << &m_integer << std::endl;

// zeige auf die speicherstelle von m_integer
m_zeiger = &m_integer;

// gib zeigerinhalt aus:
std::cout << "Integer Wert: " << *m_zeiger
          << " Speicherstelle: " << m_zeiger << std::endl;



Das sind erstmal die Basisoperationen die auf Zeiger arbeiten.
Warum Zeiger koennte man sich nun fragen!? Ein Beispiel:
Eine funktion

Code:

function(type param1){...}


bekommt einen parameter vom typ type. Dieser Parameter ist nun leider ca 16Gb gross. Soweit kein problem, aber was passiert wenn man diese Funktion mit dem parameter nun aufruft?...

Richtig, der wert param1 wird erstmal kopiert das heisst wir brauchen 16gb fuer param1 vor dem aufruf und weitere 16gb wenn wir die funktion dann wirklich aufrufen. Da wir nicht unendlich viel Speicher frei haben waere es sinnvoller der funktion einfach zu sagen wo der parameter liegt, dann muessten wir ihn nicht kopieren. Das ganze geht natuerlich mit zeigern:

Code:


void function(type *param1)
{
..
}



Strings Top



Namespaces Top



Namespaces sind Gruppen von Variablen, Objekten, Funktionen, die unter einem Namen definiert wurden. Dank ihnen lassen sich Namenskonflikte vermeiden.

Das ganze schaut so aus:

Code:


namespace Name
{
  Inhalt
}



Auf die Elemente im Namespace wird so zugegriffen:

Name::Element;

Hier ein reeles Beispiel:

Code:



namespace Test
{
   int iHallo = 3;
   int iTest = 55;
 
   int GetInt(){ return 0; }
};


namespace Blubbfish
{
   int iHallo = 1011;
 
   int GetInt(){ return 66; }
};

int main(int args, char* argv[])
{
   std::cout << "Namespace Test: iHallo: " << Test::iHallo << " GetInt(): " << Test::GetInt() << "\n" << std::endl;

   std::cout << "Namespace Blubbfish: iHallo: " << Blubbfish::iHallo << " GetInt(): " << Blubbfish::GetInt() << "\n" << std::endl;
}

Ausgabe:

Namespace Test: iHallo: 3 GetInt(): 0

Namespace Test: iHallo: 1011 GetInt(): 66



Wir haben jetzt 3 globale Variablen angelegt, auf die wir danach mit Name::Element zugegriffen haben.

Das gleiche Prinzip haben wir übrigens schon mehrfach mit std:: verwendet laugh

Wir können ausserdem alternative Namensräume mit namespace new_name = current_name ; schaffen.

Damit ein namespace in der gesammten Datei global wird kann man using namespace namespace_name; verwenden, dadurch kann es aber (vor allem in unserem Fall) zu Namenskonflikten kommen.

Beispiel:


#include <iostream>

using namespace std;

int main(int args, char* argv[])
{
   cout << "hallo!" << endl;
   return 0;
}



Ich ziehe die std:: Methode aber vor!

Für ein Objekt die in keinem Namespace ist kann man ::Objekt benutzen:

std::cout << ::iTest;

Weblinks Top



www.msdn.com - MSDN.com Die Entwickler Datenbank von Microsoft
www.mathematik.uni-marburg.de/~cpp - Ein Kurs der Uni Marburg Seite nicht mehr verfügbar!
tutorial.schornboeck.net/inhalt.htm - Ein sehr gutes C++ Tutorial Seite nicht mehr verfügbar!
www.mindview.net/Books/TICPP/ThinkingInCPP2e.html - ein Online Buch
www.volkard.de/vcppkold/inhalt.html - C++ Tutorial von Volkard Henkel Seite nicht mehr verfügbar!
www.c-plusplus.de/tutorials.htm - eine C++ Tutorialsammlung
www.volkard.de/vcppkold/inhalt.html - Volkards C++-Kurs Den Link gibt es schon! (s.o.)
ladedu.com/cpp/ - Einführung in C++
www.tutorialpage.de/Cpp2/main.php - C++-Programmierung für Einsteiger Seite nicht mehr verfügbar!
www.math.uni-wuppertal.de/~axel/skripte/oop/start.html - Objektorientiertes Programmieren mit C++
www.inf.fu-berlin.de/lehre/kurse/cplusplus/Skript.book.html - C++-Kurs Seite nicht mehr verfügbar!
www.mut.de/media/buecher/VCPLUS6/data/start.htm - Visual C++ in 21 Tagen Seite nicht mehr verfügbar!
www.mathematik.uni-marburg.de/~cpp/ - C++ Eine Einführung Den Link gibt es schon! (s.o.)
www.comnets.rwth-aachen.de/doc/handout/handout.html - Objektorientierte Programmierung in C++
www.kompf.de/cplus/index.html - Objektorientiertes Programmieren in C++
alpha.fesg.tu-muenchen.de/dieter/oop/vorlesung.html - Eine OOP/C++ Vorlesung Private Seite ohne Bezug zu C++!
www.home.unix-ag.org/martin/c++.ring.buch.html - Einführung in C++ Seite nicht mehr verfügbar!
os.inf.tu-dresden.de/~jn4/cppkurs/ - Ein kleiner Kurs in C++ Seite nicht mehr verfügbar!
www.shinigurai.de/Start.html - C++ Seite nicht mehr verfügbar!
www.bonn-online.com/~solar/cpp/contens/map.htm - Solars C++ Kurs Seite nicht mehr verfügbar!
www.ges-training.de/Expertentips/C++-Regeln/cpp_tabelle.html - Entwicklungsregeln für C++-Klassen Seite nicht mehr verfügbar!
www.wi-bw.tfh-wildau.de/~hendrix/grundstudium/cpp/skript/vererbung.... - Vererbung in C++ Seite nicht mehr verfügbar!
cpp.programmersbase.net/ - CPP.ProgrammersBase.NET
www.cpp-programming.de/ - Eine Seite, mit sehr vielen Quellcodes

Literatur Top



- Bjarne Stroustrup: Die C++ Programmiersprache, ISBN: 3-8273-1660-X, das Standardwerk zu C++, Nicht für Einsteiger geeignet, sehr empfehlenswert

Autoren & ihre Arbeit am Tutorial Top



- Simon Hecht Hauptautor

Dank geht an: Gothreaper, mazze, yannikim[b]

Gibt es noch irgendwelche Fragen, oder wollen Sie über den Artikel diskutieren?

Editieren Versionen Linkpartnerschaft Top Printversion

Haben Sie einen Fehler gefunden? Dann klicken Sie doch auf Editieren, und beheben den Fehler, keine Angst, Sie können nichts zerstören, das Tutorial kann wiederhergestellt werden

Sprachenübersicht/Programmierung/C / C++/ C#/C++ Tutorial Teil 1