C++ 2005 Tutorial
C++ 2005 Tutorial
C++ 2005 Tutorial
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.
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 eine
kleines 3D-Spiel.
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, das 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
Software Top
Vor's losgeht brauchst du noch einen Compiler bzw. eine IDE, hier solltest du etwas finden:
www.c-plusplus.de/compiler.htm
Wenn du bereit bist etwas Geld auszugeben, würde ich dir MS C++ Studio .net empfehlen, ein IDE
das zwar sehr teuer ist, aber dafür auch sehr Leistungsfähig.
Kapitel 1: Grundlagen Top
Ok, nachdem du die IDE gestartet hast, und ein neues Projekt angefangen hast, können wir
anfangen:
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.
#include <iostream>
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, das 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 gesetz, und ebenfalls kein .h verwendet. (#includ
e <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 kein String offen ist.
Jetzt sagen wir der Konsolleanwendung das das Programm ordnungsgemäß, ohne Probleme beendet
wurde: return 0;
using namespace std; wird später erklärt, dazu brauchst du noch weiteres Wissen.
Das nächste Programm Top
Ich hoffe du hast die Erklärung vom letzen Programm verstanden, wenn nicht kannst du im Forum
fragen.
Kommentare
Ok, nimm das erste Programm, und füge folgendes am Anfang hinzu:
Code:
/*
main.cpp
*/
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.
Tippe jetzt folgende Zeilen ab, und kopier sie zwischen die beiden {} Klammern, nach int main().
Code:
main.cpp
*/
#include <iostream>
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;
}
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.
Ausgabe: Text1Text2
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
cout gibt den Text in einen Ausgabenbuffer, das ist einfach ein Stück Speicher, das reserviert wurde.
Der Ausgabebuffer normalerweise am Schluss geleert wird, aber manchmal kann der auch
durcheinander kommen, und darum verwendet man cout.flush();
cout.flush(); macht einfach das 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.
1. \n
2. cout.flush();
d.h. Zuerst wird eine neue Zeile angefangen, und danach wird der String ausgegeben.
Variablen Top
Man kann ihnen einfach einen Wert zuweisen, und wieder auslesen.
Bevor man eine Variable benutzen kann muss man sie initialisieren, um Fehler vorzubeugen, und
die richtige Größe benutzen zu können.
/*
main.cpp
*/
#include <iostream>
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:
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 im Deutschen mit einem Beistrich, 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
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.
Cin funktioniert ähnlich wie cout, nur das der Operator in die andere Richtung zeigt: >>
Code:
/*
main.cpp
*/
#include <iostream>
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;
//Die Folgende Zeile addiert zuerst MeineVariable & MeineVariable, setzt zuerst MeineZweiteVaria
ble, und dann i auf das Ergebniss
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.
/*
main.cpp
*/
#include <iostream>
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:
Ein weiterer Operator ist der Modulo-Operator, er gibt den Rest einer ganzzahlen Division zurück;
Es gibt noch einen Operator: sizeof. Er gibt die Größe der Variable in Bytes zurück.
Code:
/*
main.cpp
*/
#include <iostream>
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ß.
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.
/*
main.cpp
*/
#include <iostream>
int main()
{
int a = 5;
int d = 0;
cin >> d;
const int b = a; //a könnte theoretisch wärend der Laufzeit geändert werden
//Runtime Konstante
int const z = 3; //Noch was, man kann const auch nach dem Variablentyp schreiben
return 0;
}
Namensvergabe Top
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
/*
main.cpp
*/
#include <iostream>
int a;
a = 33;
b = 3;
a = 3343;
b = 45;
c = 3;
a = 3343;
b = 45;
c = 3;
d = 343;
}
//2. Unterebene Ende
return 0;
}
//Lokaler Gültigkeitsbereich von main Ende
- 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>
int a = 3;
int a = 55;
{ // ü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.
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>
int main()
{
int a,b;
cout << "Gitte 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 Klamm
ern 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 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";
}
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>
int main()
{
int a,b;
cout << "Gitte geben Sie bitte eine Zahl ein:" << endl;
cin >> a;
cout << endl << "Gitte geben Sie bitte nochmal eine Zahl ein:" << endl;
cin >> b;
if (a = 3)
cout << endl << endl << "Das hier beweist, das = einen Wert zuweist, und immer true zurückli
efert." << 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 (t
rue 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>
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 << "Zweit";
else
cout << "Die Zahl ist größer als zwei";
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, das 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. ein 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.
/*
main.cpp
*/
#include <iostream>
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:
43+2 ist 45
Geben Sie bitte eine Zahl ein (0=Quit) 2
Anzeigen
Object 1
3+2 ist 5
Geben Sie bitte eine Zahl ein (0=Quit) 5
5+2 ist 7
Geben Sie bitte eine Zahl ein (0=Quit) 0
Bei einer normalen while Schleife kann es sein, das 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>
int main()
{
bool bLoop = false; //Eine boolsche Variable, sie kann entweder false (0) oder true(!0)
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
Aber welche Variante ist am besten? Keine, den 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.
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 if-Schleife optimal dafür geeignet.
Nehmen wir an, wir wollen eine Zahl potenzieren. Dann multiplizieren wir die Basis einige
Durchläufe mit sich selbst.
#include <iostream>
using namespace std;
int main()
{
int iBase,n = 0;
int iCalculate = 1;
cout << "\nWie oft wollen Sie sie mit sich selbst multiplizieren?:\n";
cin >> n;
cout << "\n\n" << iBase << " hoch " << n << " = " << iCalculate << "\n\n";
return 0;
}
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 == false 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 Bedingen angeben, die dann mit einem ,
getrennt werden.
z.B:
Code:
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;
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.
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 verringert, und dann bekommt i den Wert von k
//i = 1
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.
Es gibt noch 2 weitere Arten, die aus C übernommen wurden, und veraltet sind, mit denen man aber
casten kann:
Code:
Merken:
C-Casts sind böse, C++ casts sind gut. C-Casts sagen nichts, wenn man sie falsch benutzt, C++ cast
s geben Fehlermeldungen aus
Hier gibt es noch ein schönes Tutorial zu dem Thema: In C++ richtig casten
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.
#include <iostream>
int main()
{
cout << "Der ASCII Code:\n";
return 0;
}
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;
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
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>
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;
//iHealthpoints[6] //Das Programm würde hier mit einem Fehler abbrechen, weil nur ein ei
ndimensionales Feld von 0 bis 5 (insgesammt 6 Felder) erzeugt wurde
}
//Legt einen Array an, ohne den Elementen einen Wert zu geben
int iTestArray[3];
int iTestArray2[3];
//iTestArray2 = {100,53,34,95,100,232}; <-- Fehler mit {} kann man nur beim reservieren zuwei
sen
return 0; //Main wird beendet, und 0 gibt zurück, dass das Programm erfolgreich ausgeführt wu
rde
}
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:
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]
int iTestArray[6][3] =
{
{100, 0, 35},
{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;
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 ).
Für sowas gibt es Funktionen, mit ihnen kann man das Programm in Module einteilen, die dann
eigenständig Arbeiten.
#include <iostream>
int main()
{
int iFirst = 3;
int iSecond = 99;
//[..]
iFirst = 5;
iSecond = 88;
return 0;
}
#include <iostream>
//[..]
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;
RückgabeTyp Funktionsname(AnzahlDerParameterVon0BisBeliebig);
Damit sagen wir dem Programm das weiter unten eine Funktion definiert wird.
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>
int main()
{
int i = 0;
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)
Beispiel:
Code:
#include <iostream>
int i = 3;
int main()
{
int iTest;
cout << "Geben Sie bitte eine Zahl ein: ";
cin >> iTest;
GiveMessageOut(iTest);
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.
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();
Initialisiere(5);
return 0;
}
void Initialisiere()
{
iVariable = 3;
}
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.
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:
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:
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 link einen Standardparameter geben, man darf dabei aber
keine Variable auslassen:
richtig:
[node=falsch]
//Nur von rechts nach link, keine Variable darf ausgelassen werden
int Test(int x = 3, int y, int z = 34);
[/note]
Wenn wir Prototypen definieren, dürfen wir das nur in den Prototypen machen, sonst gibt der
Compiler einen Fehler aus:
Code:
#include <iostream>
Ü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:
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>
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);
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
Strings Top
Namespaces Top
Namespaces sind Gruppen von Variablen, Objekten, Funktionen, die unter einem Name definiert
wurde. Dank ihnen lassen sich Namenskonflikte vermeiden.
namespace Name
{
Inhalt
}
Name::Element;
namespace Test
{
int iHallo = 3;
int iTest = 55;
namespace Blubbfish
{
int iHallo = 1011;
std::cout << "Namespace Blubbfish: iHallo: " << Blubbfish::iHallo << " GetInt(): " << Blubbfish:
:GetInt() << "\n" << std::endl;
}
Ausgabe:
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
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>
Für ein Objekt die in keinem Namespace ist kann man ::Objekt benutzen:
std::cout << ::iTest;
Weblinks Top
Literatur Top