Mittwoch, 31. Oktober 2012

Prä- und Postfix Inkremente bzw. Dekremente

Da es bei diesem Thema häufig zu Missverständnissen kommt, sei hier nur kurz erklärt wo der Unterschied zwischen dem Prä- und dem Postfix Inkrement bzw. Dekrement liegt.

Der Unterschied ist nicht, dass a++ -> a=a+1 bzw a-- -> a=a-1 und ++a -> a=1+a bzw --a -> a=1-a. Diese Annahme fürt vor Allem bei --a häufig zu Fehlern.

Sowohl a++ / a-- und ++a /--a addieren bzw. subtrahieren den Wert 1 zu / von a.
Sprich --a -> a=a-1 und nicht 1-a!

Der große Unterschied ist jedoch, dass prä-Inkremente / Dekremente sofort der Variablen zugewisen werden und post-inkrementierte / dekrementierte Variablen erst nach der nächsten Verwendung um 1 erhöht werden.

Beispielcode in C++

01: int i = 1;
02: cout << ++i << endl;
03: cout << i++ << endl;
04: cout << ++i << endl; 

Beispielcode Java

01: int i = 1;
02: System.put.println(++i);
03: System.put.println(i++);
04: System.put.println(++i);

Ausgabe:
2
2
4

Montag, 27. August 2012

Verzweigen mit switch und case

Wie im letzten Beitrag geht es auch nun wieder um Verzweigungen innerhalb eines Programms. Diesmal werde ich euch eine Alternative zu if, else und else if vorstellen. Es handelt sich dabei, welch Überraschung, um switch und case. Diese Methode macht meist dann Sinn, wenn man sehr viele Bedingungen hintereinander prüfen will, da dadurch der Schreibaufwand verringert wird. Nun kommt aber wie immer erst der Code und danach die Erklärung.
01: #include <iostream>
02: 
03: using namespace std;
04:
05: int main()
06: {
07:     //Steuerung mit den Tasten 'W', 'S', 'A' und 'D' realisieren
08:     char chTaste;
09:
10:     switch (chTaste)
11:     {
12:       case ('w'):
13:       {
14:         cout << "Spieler geht vorwärts.\n";
15:       } break;
16:       case ('s'):
17:       {
18:         cout << "Spieler geht rückwärts.\n";
19:       } break;
20:       case ('a'):
21:       {
22:         cout << "Spieler geht nach links.\n";
23:       } break;
24:       case ('d'):
25:       {
26:         cout << "Spieler geht nach rechts.\n";
27:       } break;
28:       default:
29:       {
30:         cout << "Falsche Eingabe!\n"
31:       }
32:     }
33:
34:     //Nach dem break geht es hier weiter
35:     system("pause");
36:
37:     return 0;
38: }
Dieses Programm soll zeigen, wie in einem Spiel die Steuerung mit der Tastatur realisiert werden kann. Natürlich ist dieser Code in einem richtigen Spiel nicht zu gebrauchen, da hier lediglich eine Meldung ausgegeben wird, wenn eine Bedingung zutrifft, aber in diesem Beispiel geht es auch in erster Linie um die switch und case-Bedingung und nicht um die Steuerung in einem Spiel.

Um switch und case benutzen zu können muss man sich zunächst eine Variable erstellen, die geprüft werden soll, in diesem Beispiel 'chTaste'. Diese schreibt man nun in runden Klammern hinter die switch-Anweisung. Danach folgt ein Block aus case-Anweisungen, die Bedingung wird ebenfalls in runden Klammern hinter das Schlüsselwort case gesetzt. Hier ist jedoch darauf hinzuweisen, dass die Bedingung hinter dem case nicht wie bei einer if-Bedingung nicht zwangsläufig in Klammern stehen muss. Hinter der Bedingung folgt dann noch ein Doppelpunkt, der die Bedingung abschliesst. Trifft eine Bedingung zu, z.B. beim drücken der Taste W, so wird der darunterstehende Code ausgeführt. Folgt, wie in diesem Beispiel ein break, so werden alle weiteren case-Anweisungen übersprungen und nach dem switch-case-Block fortgefahren. Jedoch kann es auch vorkommen, dass man sich vertippt und anstallt W die Taste E drückt, in diesem Fall kommt die default-Anweisung ins Spiel. Diese ersetzt sozusagen das Schlüsselwort else aus dem vorherigen Beitrag. In einem switch-case-Block kümmert sich das default also um alle anderen Eingaben oder Bedingungen, die man in seinem Programm nicht benötigt.

Dienstag, 14. August 2012

Bedingungen in C++

Das A und O eines jeden Programmes ist, auf verschiedene Situationen unterschiedlich zu reagieren. Ein Beispiel wäre: Wenn die Esc-Taste gedrückt wurde wird das Programm beendet. In C++ gibt es dafür verschiedene Möglichkeiten, die sehr einfach zu verstehen sind. Fangen wir einfach mal an.

Die if-Bedingung

Die if-Bedingung wird in der Regel immer dann benutzt, wenn man bestimmte Werte oder Operanden miteinander vergleichen will. Im folgenden Code sieht man, wie man diese in ein Programm einbaut.

01: #include 
02: 
03: using namespace std;
04:
05: int main()
06: {
07:     int Highscore = 500;  
08:     int Score     = 0;    
09:
10:     cout << "Bitte gib deine erreichte Punktzahl an: ";
11:     cin >> Score;
12:
13:     if (Score > Highscore)
14:     {
15:         cout << "Sie haben einen neuen Highscore erreicht \n";
16:         Highscore = Score;
17:     }
18:
19:     return 0;
20: }

Dieses kleine Programm prüft, ob man in einem Spiel einen neuen Highscore erreicht hat. Der erreichte Score muss zwar noch selbst eingegeben werden, was in einem richtigen Spiel natürlich nicht der Fall ist, jedoch geht es hier in erster Linie um die if-Bedingung.
Diese prüft in Zeile 13, ob der erreichte Score größer ist als der aktuelle Highscore. Hier können alle boolschen Operatoren ( ==, !=, <, >, <=, >= ) verwendet werden, um den gewünschten Vergleich durchzuführen. Natürlich kann man auch einen geringeren oder gar die selbe Punktzahl wie der Highscore erzielen. Dazu kann man sich 2 weitere if-Bedingungen erstellen, die die gewünschten Vergleiche durchführen, oder man benutzt die else-Bedingung.

Die else-Bedingung

Eine else-Bedingung wird immer zusammen mit einer if-Anweisung verwendet. Sie bedeutet soviel, wie anderenfalls oder ansonsten und kann folgendermaßen verwendet werden.

01: #include 
02: 
03: using namespace std;
04:
05: int main()
06: {
07:     int Highscore = 500;  
08:     int Score     = 0;    
09:
10:     cout << "Bitte gib deine erreichte Punktzahl an: ";
11:     cin >> Score;
12:
13:     if (Score > Highscore)
14:     {
15:         cout << "Sie haben einen neuen Highscore erreicht \n";
16:         Highscore = Score;
17:     }
18:     else if (Score == Highscore)
19:     {
20:         cout << "Sie sind gleich auf mit dem Highscore \n";
21:     }
22:     else
21:     {
22:         cout << "Sie haben zu wenig Punkte für den Highscore erreicht \n";
23:     }
24:
25:     return 0;
26: }

Hier wird, wie oben beschrieben mit Hilfe der else-Anweisung geprüft, ob die erreichte Punktzahl größer, gleich oder geringer als der Highscore ist. Ihr fragt euch sicher, warum hinter dem letzten else kein Vergleich durchgeführt wird. Nunja, da ein Wert nur größer, gleich, oder kleiner als ein anderer Wert sein kann, können wir uns Tipparbeit sparen und dem Compiler durch das alleinstehende else sagen, dass für alle anderen Fälle ( also in diesem Fall nur kleinere Werte, da wir größer und gleich ja schon getestet haben ) der darunterstehende Code ausgeführt werden soll.

Donnerstag, 26. Juli 2012

Buchempfehlung: Prata, Stephen - C++ Primer Plus 6th Edition (2012)

  • geeignet für: Anfänger und Fortgeschrittene
  • Sprache: Englisch
  • Behandelt fast alle Aspekte der C++-Programmierung sehr ausführlich und verständlich
  • Bietet außerdem einen ausführlichen Einblick in den neuen Standard C++11
  • sehr umfangreich (ca. 1400 Seiten)
ISBN: 978-0-321-77640-2 Preis: 39,95€

Freitag, 6. Juli 2012

Texteingabe mit Arrays

Einführung

Nachdem wir nun wissen wie man mit C++ rechnet ist es an der Zeit seinen eigenen Text in ein Programm eingeben zu können. Es gibt verschiedene Möglichkeiten Text in ein Programm einzugeben, in diesem Tutorial wollen wir uns jedoch erstmal den Arrays widmen.

Arrays

Arrays sind eine feine Sache, denn mit deren Hilfe ist es möglich sehr viele Variablen des gleichen Datentyps schnell und unkompliziert zu deklarieren. Schauen wir es uns einfach mal an:

int array[10];

Mit diesem Aufruf hat man nun 10 Variablen des Datentyps Integer deklariert. Dies ist viel einfacher, als wenn man jede Variable einzeln deklarieren muss, etwa so:

int array1, array2, array3 ...

Um nun die einzelnen Variablen mit Werten zu füllen, sucht man sich einfach die gewünschte Variable raus und weist ihr einen Wert zu. Wichtig dabei zu Wissen ist, dass Arrays grundsätzlich bei 0 beginnen. Ein Array der Größe 10 kann also im Bereich 0-9 aufgerufen werden. Schauen wir uns das einfach mal an:

01: int array[10];
02:
03: array[0] =  1;
04: array[1] =  2;
    ...
12: array[9] = 10;

Würde man nun array[10] definieren wollen, so würde ein Fehler vom Compiler ausgegeben werden.

Man kann auch dynamische Arrays erstellen das bedeutet, dass sich das Array automatisch der benötigten Größe anpasst. Außerdem ist es möglich Arrays, genau wie alle anderen Variablen gleichzeitig zu deklarieren und zu definieren. In der Praxis sieht das ganze so aus:

int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Dies erstellt ein Array mit 10 Integer Werten und weist jedem Element der Reihe nach einen Wert zu.

Auf gleiche Weise ist es nun auch möglich Text zu schreiben. Man erstellt sich einfach ein unbestimmtes Array des Datentyps char und weist ihm Text zu. Das ganze schaut dann so aus:

char array[] = "Dieser Text wurde in einem Array erstellt."

Texteingabe mit 'cin'

Möchte man in seinem Programm manuell Text eingeben können, so geschieht dies mit dem Schlüsselwort cin. Es ist genauso einfach zu verwenden wie cout nur, dass man noch eine zusätzliche Variable erstellen muss. Hier ein kleines Beispiel mit Zahlen:

01: int zahl;
02: 
03: std::cin >> zahl;
04:
05: std::cout << zahl;

Dieses Programm erwartet vom Benutzer die Eingabe einer Zahl, dies könnte in der Praxis zum Beispiel das Alter sein. Diese Zahl wird danach wieder vom Programm ausgegeben.

Um jedoch Text eingeben zu können benötigen wir wieder unsere Arrays. Wenn man weiß, wie lang der Text werden soll ist es empfehlenswert dem Array diese Größe zuzuweisen, z.B. array[50]. Weiß man die Länge des Textes jedoch nicht, so sollte man ein sehr großes Array, z.B. array[1000] erstellen oder Strings verwenden (Diese werde ich aber erst in späteren Tutorials vorstellen). Nun aber zur Praxis:

01: char Name[50];
02:
03: std::cin.get (Name, 49);
04:
05: cout << Name;

Dieses Programm eignet sich ganz gut, wenn man den Namen eines Benutzers, z.B. für eine Highscoreliste erfahren möchte. Mit cin.get() kann man dem Array einen Text zuweisen, welcher maximal die angegebene Größe haben darf.

Samstag, 23. Juni 2012

Buchempfehlung: Dawson, Michael - Beginning C++ Through Game Programming (2010)

  • geeignet für: Anfänger
  • Sprache: Englisch
  • Erklärt alle für die Spieleprogrammierung relevanten Aspekte der C++-Programmierung sehr ausführlich und verständlich
  • Bietet anschauliche Beispiele aus dem Bereich der Spieleprogrammierung
  • umfangreich (ca. 400 Seiten)
ISBN: 978-1-435-45742-3 Preis: 27,70€

Montag, 18. Juni 2012

Verwendung von Variablen und Operatoren

Ein Programm welches nur Text ausgeben kann ist ziemlich langweilig, nicht wahr? Aus diesem Grund werde ich in diesem zweiten Tutorial zeigen, wie man mit seinem Programm rechnen kann.
Zunächst passiert eigentlich nichts neues, man muss lediglich den Header <iostream> einbinden, den Standard-Namensbereich festlegen und die main-Funktion aufrufen.

01: #include <iostream>
02:
03: using namespace std;
04:
05: int main()
06: {

Nun muss man sich überlegen, was man eigentlich zum rechnen benötigt. Selbstverständlich benötigt man zwei Operanden , einen Rechenoperator (+, -, *, /, %) und das "Gleichzeichen" ( = ).
Zunächst erstellt man sich 3 Variablen, zwei welche die Operanden speichern und eine welche das Ergebnis beinhaltet. Das hört sich jetzt vielleicht für einige kompliziert an, ist es aber keineswegs.

01: #include <iostream>
02:
03: using namespace std;
04:
05: int main()
06: {
07:     int op1;  //Operand 1
08:     int op2;  //Operand 2
09:     int erg;  //Ergebnis

Hier wurden 3 Variablen vom Typ int erstellt. Variablen vom Typ int können nur Ganzzahlen speichern, möchte man jedoch mit Dezimalzahlen rechnen, sollte man den Datentyp float oder double verwenden. Nun kann man aber noch nicht viel mit diesen Variablen anstellen, da ihnen noch keine Werte zugewiesen wurden. Dies geschieht mit Hilfe des Zuweisungsoperators ( = ). In diesem Beispiel wird die Anzahl der Pixel eines Monitors berechnet. Möchte man zum Beispiel wissen, wie viele Pixel ein 1680x1050 großer Monitor hat, so weist man den Operatoren die Werte für Höhe und Breite zu. Der Ergebnisvariablen weist man daraufhin das Ergebnis der Multiplikation beider Operatoren zu. Zum Schluss wird das Ergebnis ausgegeben.

01: #include <iostream>
02:
03: using namespace std;
04:
05: int main()
06: {
07:     int op1;  //Operand 1
08:     int op2;  //Operand 2
09:     int erg;  //Ergebnis
10:
11:     op1 = 1680;
12:     op2 = 1050;
13:
14:     erg = op1 * op2;
15:
16:     cout << "Der Bildschirm hat eine Auflösung von " << op1 << "x"
17:          << op2 << " das sind " << erg << " Pixel" << endl;
18: 
19:     return 0;
20: } 

Ihr fragt euch jetzt sicher, wo der Sinn dieses Programms liegt. Doch ist es sehr wichtig zu wissen, wie man in C++ rechnet, wenn man später komplexe Programme oder sogar Spiele programmieren will, auch wenn das in diesem Beispiel noch nicht erkenntlich wurde.

Sonntag, 10. Juni 2012

Ankündigung: Visual Studio Express 2012 for Windows Desktop

Entgegen den ursprünglichen Plänen Microsofts, ausschließlich eine kostenlose Express-Version des neuen Visual Studios 2012 für Anwendungen im Metro-Style bereitzustellen, wird nun doch eine kostenlose Express-Version für Desktop-Anwendungen erscheinen. Dies berichtete das Entwicklerteam von Visual Studio auf seinem Blog.
Die neue Version wird unter dem Namen Visual Studio Express 2012 for Windows Desktop erscheinen und die Programmiersprachen C++, C# und Visual Basic unterstützen. Darüber hinaus soll diese Version die aktuellsten Compiler und Entwicklungswerkzeuge beinhalten.
Mit dieser Masnahme reagiert Microsoft auf die Kritik vieler Entwickler, die für die Entwicklung von Desktop-Anwendungen nicht auf die kostenpflichtige Version des neuen Visual Studio 2012 zurückgreifen wollten.

Mittwoch, 6. Juni 2012

Tic Tac Toe

Heute stelle ich euch mein neustes Projekt vor. Diesmal handelt es sich um einen Klassiker der Spielgeschichte :) . Tic Tac Toe war lange Zeit das beste Mittel gegen Langeweile, vor Allem während den Pausen in der Schule. Nun kehrt es zurück auf euren Bildschirm. Viel Spass damit!

Update: 02.03.2013 - Version für Linux hinzugefügt

Downloads:
Download 1 (Programm Windows)
Download 2 (Programm Linux)
Download 3 (Sourcecode Windows)
Download 4 (Sourcecode Linux)

Freitag, 1. Juni 2012

Zahlensysteme (Dezimal, Hexadezimal und Binär)

Einleitung

Es gibt viele verschiedene Systeme um bestimmte Zahlen darzustellen. Das bekannteste ist wohl das Dezimalsystem, in dem jede beliebige Zahl mit Hilfe der Ziffern 0-9 dargestellt werden kann. In der Programmierung trifft man jedoch auch häufig auf andere Arten der Zahlendarstellung, wie dem Hexadezimalsystem oder dem wohl wichtigsten in der Computerwelt, dem Binärsystem


Dezimalsystem

Basiszahlen         : 10 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Zahlendarstellung   : 1, 234, 5.6 ...
Berechnungsbeispiel : 234
                      2*102
                    +  3*101
                    +   4*100
                    = 200 + 30 + 4
                    = 234 

Hexadezimalsystem

Basiszahlen         : 16 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F)
                      A = 10, B = 11, C = 12, D = 13, E = 14, F = 15
Zahlendarstellung   : 12, AB, D3F ...
Umrechnungsbeispiel : D3F
                      D*162
                    +  3*161
                    +   F*160
                    = 12*256 + 3*16 + 15*1
                    = 3072 + 48 +15
                    = 3135

Binärsystem

Basiszahlen         : 2 (0, 1)
Zahlendarstellung   : 10, 0101, 1001 ...
Umrechnungsbeispiel : 1010
                      1*23
                    +  0*22
                    +   1*21
                    +    0*20
                    = 1*8 + 0*4 + 1*2 + 0*1
                    = 8 + 0 + 2 + 0
                    = 10
Wie euch bestimmt aufgefallen ist gibt es eine bestimmte Regel, mit welcher man jede beliebige Zahl eines Zahlensystems in eine Dezimalzahl umrechnen kann. Diese möchte ich hier kurz voretsllen.

Dezimalzahl = [Ziffer] * [Basiszahl][Exponent]
Der Exponent bildet sich aus der Anzahl der Ziffern einer Zahl. Es gilt:
Exponent -> ...[4][3][2][1][0].[-1][-2][-3]...
(in den eckigen Klammern steht der Exponent der Ziffern vor und hinter dem Komma)

Das ist zwar sehr hilfreich, aber wie berechnet man eine Dezimalzahl in eine Binär oder Hexadezimalzahl um, und wie bestimmt man die Binärzahl einer Hexadezimalzahl und andersrum? Dies werde ich nun erklären.

Dezimal -> Hexadezimal

Beispiel:

Zahl = 1234
Basiszahlen (Hexadezimal) = 16

1234 / 16 = 77      Rest:   2
    77 / 16 =   4      Rest: 13
      4 / 16 =   0      Rest:   4

Nun muss man die Rest-Ziffern von unten nach oben lesen, aus zweistelligen Zahlen werden bekanntlich Buchstaben, also ist der

Hexadezimalwert = 4D2

Dezimal -> Binär

Beispiel:

Zahl = 1234
Basiszahlen (Binär) = 2

1234 / 2 = 617     Rest: 0
  617 / 2 = 308     Rest: 1
  308 / 2 = 154     Rest: 0
  154 / 2 =   77     Rest: 0
    77 / 2 =   38     Rest: 1
    38 / 2 =   19     Rest: 0
    19 / 2 =     9     Rest: 1
      9 / 2 =     4     Rest: 1
      4 / 2 =     2     Rest: 0
      2 / 2 =     1     Rest: 0
      1 / 2 =     0     Rest: 1

Auch hier müssen die Rest-Ziffern wieder von unten nach oben gelesen werden. Die Dezimalzahl 1234 ergibt im Binärsystem also

Binärwert = 10011010010

Hexadezimal -> Binär


0 = 0000    6 = 0110    C = 1100
1 = 0001    7 = 0111    D = 1101
2 = 0010    8 = 1000    E = 1110
3 = 0011    9 = 1001    F = 1111
4 = 0100    A = 1010
5 = 0101    B = 1011

Beispiel:

Zahl = B7

B = 1011
7 =  0111
Binärwert = 10110111

Binär -> Hexadezimal

Zahl = 1010 0101 1101
1010 = A
0101 = 5
1101 = D

Hexadezimalwert = A5D

Montag, 28. Mai 2012

Buchempfehlung: Kalista, Heiko - C++ für Spieleprogrammierer (2009)

  • geeignet für: Anfänger
  • Erklärt alle wichtigen Aspekte der C++-Programmierung sehr verständlich
  • Bietet anschauliche Beispiele aus dem Bereich der Spieleprogrammierung
  • Leitet den Leser sehr gut von den grundlegenden Kenntnissen zum ersten selbst programmierten Spiel
ISBN: 978-3-446-42140-0 Preis: 34,90€

Randomizer

Der Randomizer (Zufallsgenerator) ist eines meiner ersten Projekte in C++. Mit ihm ist es möglich aus beliebig viele Eingaben eine zufällige auszuwählen. Wer möchte kann den Randomizer auch weiterentwickeln und an seine Bedürfnisse anpassen. Viel Spass beim Ausprobieren!

Update: 24.02.2013 - Bugfixes, kann nun mit beliebig vielen Eingaben umgehen
Update: 28.02.2013 - Bugfixes, verschiedene Versionen für Linux und Windows
Update: 09.05.2013 - kann nun auch Dateien lesen (Ein Element pro Zeile)

Downloads:
Download 1 (Sourcecode)
Download 2 (Programm Linux)
Download 3 (Programm Windows)

Sonntag, 27. Mai 2012

Die C++ Standard-Bibliothek

Die C++ Standard-Bibliothek stellt einige "Werkzeuge" zur Verfügung, mit deren Hilfe das Programmieren sehr viel einfacher wird. Einen Bestandteil dieser Library haben wir bereits in meinem ersten C++ Tutorial kennengelernt, nämlich die Datei iostream, welche durch #include eingebunden wurde. Neben der Ein- und Ausgabe von Text stellt die C++-Standard-Library noch 8 weitere Klassen bzw. Funktionen zur Verfügung. Die 9 Bestandteile sind:
  • String
  • Numerische Berechnungen
  • Fehlerbehandlung
  • Ein- und Ausgabe
  • Laufzeit-Typerkennung
  • Nationale Besonderheiten
  • Speicher-Verwaltung
  • Hilfsfunktionen
  • Standard Template Library (STL)
Was diese Funktionen und Klassen bewirken und wie man sie anwendet werde ich später in diesem Post noch erklären.
Wer meinen Artikel Einführung in C++ gelesen hat weiß, dass der Vorgänger von C++ die Programmiersprache C ist. Aus diesem Grund beinhaltet die C++ Standard-Library auch die C-Standard-Library, welche 18 Header-Dateien bereitstellt. Diese werde ich in der folgenden Tabelle vorstellen.

Header-Datei Erklärung
<cassert> Wenn der Ausdruck nicht wahr ist, bricht das Programm mit einer Fehlermeldung ab
<cctype> Klassifizierung von Zeichen
<cerrno> Error-Fehlernummern für Bibliotheksfunktionen
<climits> Minimaler und maximaler Wert von Ganzzahl-Typen
<cfloat> Minimaler und maximaler Wert von Fließkommazahl-Typen
<ciso646> Operatormakros
<clocale> Kulturelle Besonderheiten abbilden
<cmath> Mathematische Funktionen
<csetjmp> Ausführung von nicht lokalen goto-Anweisungen
<csignal> Aktion, die bei einem bestimmten Signal ausgelöst wird
<cstdarg> Variable Argumentenlisten für Funktionen mit einer variablen Anzahl von Parametern
<cstddef> Definition von einfachen Typen und Makros wie z.B. den NULL-Zeiger
<cstdio> Ein- und Ausgabe auf die Konsole oder in Dateien
<cstdlib> Allgemeine Funktionen, z.B. zur Erstellung von Zufallszahlen
<cstring> C-Funktionen für nullterminierte Zeichenfelder
<ctime> Zeit- und Datumsfunktionen
<cwchar> Umwandlung von Strings zu Zahlen für den Unicode-Zeichensatz
<cwctype Zeichenuntersuchung für den Unicode-Zeichensatz

Diese Headerdateien müssen mit der Anweisung #include eingebunden werden. Desweiteren nutzen alle Header den Namensraum std, den wir im ersten C++ Tutorial bereits kennengelernt haben.

Nun werde ich, wie versprochen, die einzelnen Bestandteile der C++ Standard-Bibliothek vorstellen, die es neben der C-Standard-Library noch gibt.

String
Header-Datei Erklärung
<string> Ermöglicht die Erstellung und Manipulation von Strings

Numerische Berechnungen
Header-Datei Erklärung
<complex> Komplexe Zahlen
<valarray> Gleitkommaberechnung mit großen Datenmengen, die auf eindimensionale Zahlenfeldern basieren
<limits> Größeninformationen, wie z.B der minimale Wert
<numeric> Funktionen zur Summenbildung, der Differenz und des Skalarprodukts

Fehlerbehandlung
Header-Datei Erklärung
<exception> Ausnahmebehandlung
<stdexept> Fehlerreports

Ein- und Ausgabe
Header-Datei Erklärung
<istream> Eingabe
<ostream> Ausgabe
<iostream> Ein- und Ausgabe mit cin, cout und cerr
<iomanip> Manipulatoren für Ein- und Ausgabe
<ios> Grundlage für die Ein- und Ausgabe
<iofwd> Grundlage für die Ein- und Ausgabe
<fstream> Zeichen aus Dateien lesen oder in Dateien schreiben
<streambuf> Ein- und Ausgabe auf gebufferten Streams
<sstream> Zeichenketten lesen und in String-Objekte schreiben

Laufzeit-Typerkennung
Header-Datei Erklärung
<typeinfo> Laufzeit-Typinformation als Text

Nationale Besonderheiten
Header-Datei Erklärung
<local> Kulturelle Unterschiede der Zeichen

Speicherverwaltung
Header-Datei Erklärung
<memory> Speicheranforderung und -freigabe
<new> Speicheranforderung

 Hilfsfunktionen
Header-Datei Erklärung
<utility> Fügt 2 Werte zu einem Paar zusammen. Elemente bestehen aus einem Wert und einem Schlüssel. Der Schlüssel dient der Identifizierung
<functional> Definiert STL-Funktionen, die helfen Objekte zu konstruieren

Donnerstag, 24. Mai 2012

Textformatierung in C++

In C++ gibt es die Möglichkeit seinen Text mit Hilfe von sogenannten Escape-Sequenzen zu formatieren. Escape-Sequenzen kennzeichnen sich dadurch, dass sie immer mit einem Backslash beginnen. In der folgenden Tabelle werden die wichtigsten von ihnen vorgestellt.

Escape-Sequenz Bedeutung
\\ fügt einen Backslash ein
\" fügt ein Anführungszeichen ein
\0 Nullzeichen (Ende einer Zeichenkette)
\n Zeilenumbruch (new line)
\t horizontaler Tabulator
\v vertikaler Tabulator
\r kehrt zum Zeilenanfang zurück (carriage return)
\b löscht das letzte Zeichen (backspace)
\a akustisches Signal


Die Einbindung von Escape-Sequenzen in einen Quelltext funktioniert sehr leicht, wie das nachfolgende Beispiel zeigt.

C++

   cout << "Textformatierung\nin \"C++\"\nist\nsehr\neinfach\n";

Java

   System.out.println("Textformatierung\nin \"Java\"\nist ebenfalls\neinfach\n";

Dienstag, 22. Mai 2012

Das erste Programm in C++

Zunächst wird eine geeignete Entwicklungsumgebung (IDE) benötigt, um C++ Programme zu programmieren. In diesem Tutorial werde ich Visual C++ 2010 Express von Microsoft verwenden, es gibt jedoch auch gute Alternativen, wie z.B Code::Blocks oder Dev-C++. Solltest du sich gegen Visual C++ 2010 Express entscheiden achte beim Download der IDE darauf, dass ein Compiler integriert ist, der im besten Fall den neusten Standard C++11 unterstützt. Anderenfalls kann der Quelltext nicht in eine ausführbare Datei (exe) umgewandelt werden. Nachdem die IDE heruntergeladen und installiert wurde, steht dem ersten Programm nichts mehr im Wege.

Jetzt geht es los

Erstelle nun ein neues Projekt und wähle "Win32-Konsolenanwendung" aus. Nun muss noch ein Name eingegeben und auf OK geklickt werden. Im nächsten Fenster muss auf "Weiter" geklickt werden und dann unter "Zusätzliche Optionen" einen Haken bei "Leeres Projekt" gesetzt werden. Nachdem das Projekt erstellt wurde fehlt noch die C++-Datei, in welcher der Code gespeichert wird. Klicke dazu auf "Neues Element hinzufügen" und wähle "C++-Datei" aus. Nachdem du auf "Hinzufügen" geklickt hast kannst du dich endlich dem wesentlichen Teil widmen, dem Code.

Der Code

In der Regel beginnt jeder Programmierer mit einem sogenannten "Hello World"-Programm, da wir dieses Ritual natürlich nicht brechen wollen, schreiben wir uns ebenfalls ein solches Programm. Zunächst werde ich hier den Code vorstellen und ihn danach erklären.

1  #include <iostream>
2  
3  using namespace std;
4  
5  int main()
6  {
7      cout << "Hello World!" << endl;
8      
9      return 0;
10 } 

Wie, nur 10 Zeilen? Ist das nicht ein bisschen wenig? Nein, dieses Programm weist bereits die grundlegende Struktur auf, die in fast jedem C++ Programm gleich ist. Aus diesem Grund wird es auch so gerne als erstes Beispiel in Tutorials genommen. Kommen wir nun zur Erklärung.

In der ersten Zeile wird die Headerdatei "iostream" durch die Präprozessor-Direktive "#include" eingebunden. Dadurch werden bestimmte Funktionen zur Verfügung gestellt, die den Input und Output, also die Ein- und Ausgabe von Text regeln. Präprozessor-Direktiven werden immer vor dem nachfolgenden Code durch den Compiler eingebunden. Es gibt neben "#include" noch viele weitere Präprozessor-Direktiven.

In der dritten Zeile wird der Standard-Namensbereich (std) eingebunden, somit können wir Funktionen oder Variablen, welche in diesem Namensbereich gespeichert sind einfacher verwenden. Anderenfalls müsste man vor jeder std-Funktion oder Variable "std::" schreiben.

Nun kommen wir zum "Herz" unseres kleinen Programms, der main-Funktion. Die main-Funktion ist Teil eines jeden C++ Programms, diese wird beim Programmstart immer als erstes aufgerufen, von ihr ausgehend wird also das komplette Programm gesteuert.
Der Code einer jeden Funktion steht innerhalb von geschweiften Klammern { }, diese signalisieren den Beginn und das Ende einer jeden Funktion.
Die main-Funktion gibt immer einen Wert vom Datentyp int zurück, wird der Wert Null zurückgegeben bedeutet dies, dass keine Fehler aufgetreten sind. Eine solche Rückgabe erfolgt in Zeile 9 durch das Schlüsselwort return.

In Zeile 7 kommt nun der interessante Teil des Programms, für diese Zeile haben wir sowohl den Header "iostream" als auch den Namensbereich "std" eingebunden. Mit Hilfe des Befehls "cout" ist es möglich Text auf den Bildschirm auszugeben. Unschwer zu erkennen ist, dass hier der Text "Hello World!" ausgegeben werden soll. Dieser Text wird mit Hilfe des Umleitungsoperators "<<" an "cout" übergeben und muss immer in Anführungszeichen stehen. Durch den Befehl "endl" wird ein Zeilenumbruch erzeugt, wodurch möglicher folgender Code in eine neue Zeile gerückt wird.

Was ebenfalls auffällt ist, dass jede Befehlszeile mit einem Semikolon endet. Dies ist notwendig, damit der Compiler erkennt, dass ein Befehl zu Ende ist. Präprozessor-Direktiven und Funktionsköpfe benötigen jedoch kein Semikolon.

Nachdem der Code vollständig eingetippt wurde muss er nur noch kompiliert werden. In Visual C++ 2010 Express muss dazu F5 gedrückt werden. Sollten ihr eine andere Entwicklungsumgebung nutzen, schaut bitte in der Anleitung nach, welche Taste für das Kompilieren verwendet wird. Nun sollte sich ein Konsolenfenster öffnen, in welchem die Worte "Hello World!" zu lesen sind.
Manchmal kommt es vor, dass sich das Konsolenfenster nach einem kurzen Moment wieder von alleine schließt. Tritt dieser Fehler auf, so könnt ihr ihn durch den Aufruf cin.get()  (vor return 0) beheben.

Sonntag, 20. Mai 2012

Operatoren in C++

Operator Bezeichnung Beschreibung Anwendung
+ positives Vorzeichen kann weggelassen werden, nur sinnvoll um explizit auf das Vorzeichen hinzuweisen int a = +1;
- negatives Vorzeichen kehrt das Vorzeichen um int a = -1;
int b = -a;
(b wird zu +1)
+ Addition addiert zwei Operanden miteinander int a;
int b;
int c = a + b;
- Subtraktion subtrahiert den rechten Operanden vom linken int a;
int b;
int c = a - b
* Multiplikation multipliziert zwei Operanden miteinander int a;
int b;
int c = a * b;
/ Division dividiert den linken Operanden durch den rechten, ein eventueller Rest fällt weg int a;
int b;
int c = a / b;
% Modulo gibt den Rest einer Division aus int a = 10;
int b = 3;
int c = a % b;
(c wird zu 1)
++ Inkrement (als Präfix-Inkrement oder Postfix-Inkrement anwendbar) erhöht den Wert des Operanden um 1 (Postfix-Inkremente haben eine höhere Priorität als Präfix-Inkremente) Postfix
int a = 1;
int b = a++;
Präfix
int a ;
int b = ++a;
(b wird zu a+1)
-- Dekrement (als Präfix-Dekrement oder Postfix-Dekrement anwendbar) verringert den Wert des Operanden um 1 (Postfix-Dekremente haben eine höhere Priorität als Präfix-Dekremente) Postfix
int a;
int b = a--;
Präfix
int a = 1;
int b = --a;
(b wird zu a-1)
= Zuweisung weist dem linken Operanden den Wert des rechten zu int a = 1;
+=, -=, *=, /=, %=, &=, <<=, >>=, ^=, |= kombinierte Zuweisungsoperatoren der linke Operator wird sowohl als linker Operator für die Zuweisung als auch für den rechten Operator verwendet a += b
(bedeutet a = a + b)
== Gleichheit vergleicht zwei Operanden miteinander, wenn beide gleich sind wird der boolsche Wert true, anderenfalls false zurückgegeben a == b
!= Ungleichheit vergleicht zwei Operanden miteinander, wenn beide ungleich sind wird der boolsche Wert true, anderenfalls false zurückgegeben a != b
<= kleiner oder gleich vergleicht zwei Operanden miteinander, wenn der linke Operand kleiner oder gleich dem rechten ist wird der boolsche Wert true, anderenfalls false zurückgegeben a <= b
>= größer oder gleich vergleicht zwei Operanden miteinander, wenn der linke Operand größer oder gleich dem rechten ist wird der boolsche Wert true, anderenfalls false zurückgegeben a >= b
< kleiner vergleicht zwei Operanden miteinander, wenn der linke Operand kleiner als der rechte ist wird der boolsche Wert true, anderenfalls false zurückgegeben a < b
> größer vergleicht zwei Operanden miteinander, wenn der linke Operand größer als der rechte ist wird der boolsche Wert true, anderenfalls false zurückgegeben a > b
&& logisches UND Verknüpft die beiden Operanden und gibt true zurück, wenn beide Operanden den Wert true besitzen, ansonsten false a && b
|| logisches ODER Verknüpft die beiden Operanden und gibt true zurück, wenn einer der Operanden den Wert true besitzt, ansonsten false a || b
! logisches NICHT aus true wird false, aus false wird true !a
& bitweises UND Verknüpft jedes Bit beider Operanden int a;
int b;
int c = a & b;
| bitweises ODER Verknüpft jedes Bit beider Operanden int a;
int b;
int c = a | b;
^ bitweises exklusives ODER Verknüpft jedes Bit beider Operanden int a;
int b;
int c = a ^ b;
~ bitweises NICHT Negiert den Wert jedes Bits int a;
int b = ~a;
<< Linksverschiebung Verschiebt die Bits des linken Operanden um die durch den rechten Operanden angegebene Anzahl von Stellen nach links und füllt die Stellen rechts mit Nullen int a;
int b;
int c = a << b;
>> Rechtsverschiebung Verschiebt die Bits des linken Operanden um die durch den rechten Operanden angegebene Anzahl von Stellen nach rechts, die nach rechts verschobenen Bits fallen weg int a;
int b;
int c = a >> b;
* Zeigerdereferenzierung Verhindert das Zugreifen auf die Adresse eines Zeigers, sodass nur auf den Speicherbereich zugegriffen wird int a = 5;
int* b = &a;*b = c;
. Elementzugriff Greift auf einen Member eines Objekts zu objekt.member = a;
-> Zugriff auf Member über Zeiger Dereferenziert einen Zeiger auf ein Objekt, der durch den linken Operanden angegeben wird, und greift auf den durch den rechten Operanden angegebenen Member zu obj_zeiger->member = a;
:: Qualifizierung Qualifizierung einer Variable, Funktion oder Klasse mit ihrem übergeordneten Element (z.B. Namespace) string a;
std::cin >> a;
.* Zugriff auf und gleichzeitige Dereferenzierung eines Members Zugriff auf und gleichzeitige Dereferenzierung eines Zeiger-Members eines Objekts objekt.*z_member = a;
->* Zugriff auf und gleichzeitige Dereferenzierung eines Members über einen Zeiger Zugriff auf, und gleichzeitige Dereferenzierung eines Zeiger-Member eines Objekt-Zeigers obj_z->*z_member = a;
& Adressoperator ermittelt die Adresse eines Operanden int a = 1;
int* zeiger = &a;
sizeof Speichergröße ermittelt den Speicherbedarf eines Datentyps bzw. eines Operanden int a = sizeof(int);
int b = sizeof a;
new Objekterstellung erstellt ein Objekt vom angegebenen Typ und gibt einen Zeiger darauf zurück Object * p = new Object(parameter);
new[] Objekt-Array-Erstellung erstellt ein neues Objekt-Array Object * object_array = new Object[12];
delete Objektzerstörung zerstört das gewünschte Objekt Object * a = new Object;
delete a;
delete[] Objekt-Array-Zerstörung Zerstört die Objekte im gewünschten Array delete[] object_array;
() Funktionsaufruf ruft eine Funktion auf function()
, Komma Operator (Aufzählung) Dient als Trennzeichen bei Initialisierungen, etc. int a, b, c;
* Zeigerdeklaration erstellt einen Zeiger auf einen bestimmten Datentypen int* zeiger;
?: Bedingungsoperator Ersatz für ein if-else Konstrukt, wenn die Bedingung in der Klammer zutrifft wird der erste Operand ausgeführt, wenn nicht der zweite int a = (b>c) ? a : b;
[] Indizierung greift auf ein bestimmtes Element im Array zu array[a] = 1;
(typ) Typumwandlung: explizites Casting in C Wandelt den Datentyp einer Variable in den gewünschten Datentyp um. Sollte jedoch in C++ so nicht verwendet werden, da Fehler auftreten können float a = 1.2;
int b = (int)a;
static_cast Typumwandlung in C++ Wandelt den Datentyp einer Variable in den gewünschten Datentyp um float a = 1.2;
int b = static_cast<int>(a);
const_cast const_cast Operator Entfernen der Konstanz von einem Datentyp, sodass ein Schreibzugriff ermöglicht wird const int a = 10;
const int b = const_cast(&a);
reinterpret_cast reinterpret_cast Operator sehr mächtiger Cast, mit dem man z.B. Zeiger in Datentypen umwandeln kann int a = 1;
float *b = reinterpret_cast<float*>(a);
typeid typeid Operator liefert während der Laufzeit Informationen über eine Variable, eine Referenz, einen (dereferenzierten) Zeiger oder eine Klasse #include <typeinfo>
class Base {/*...*/};
class Derived : public Base {/*...*/}
Derived dobj;
Base &bref = dobj;
if (typeid(bref) == typeid(Derived))
{
std::cout << "bref referenziert Derived" << std::endl;
}

Donnerstag, 17. Mai 2012

Datentypen in C++

Datentyp Speicherbedarf Beschreibung Wertebereich
int 4 Byte Ganzzahl (positiver und negativer Wertebereich) -2147483648 bis +2147483647
signed int 4 Byte Ganzzahl (positiver und negativer Wertebereich) -2147483648 bis +2147483647
unsigned int 4 Byte Ganzzahl (positiver Wertebereich) 0 bis +4294967295
short 2 Byte Ganzzahl (positiver und negativer, kleiner Wertebereich) -32768 bis +32767
signed short 2 Byte Ganzzahl (positiver und negativer, kleiner Wertebereich) -32768 bis +32767
unsigned short 2 Byte Ganzzahl (nur positver, kleiner Wertebereich) 0 bis +65536
long 4 Byte Ganzzahl (positiver und negativer, großer Wertebereich) -2147483648 bis +2147483647
signed long 4 Byte Ganzzahl (positiver und negativer, großer Wertebereich) -2147483648 bis +2147483647
unsigned long 4 Byte Ganzzahl (nur positver, großer Wertebereich) 0 bis +4294967295
float 4 Byte Gleitkommazahl (positiver und negativer Wertebereich, auf 7-8 Stellen genau) -3,4x1038 bis +3,4x1038
double 8 Byte Gleitkommazahl (positiver und negativer Wertebereich, auf 15-16 Stellen genau) -1,7x10308 bis +1,7x10308
long double 10 Byte Gleitkommazahl (positiver und negativer Wertebereich, auf 19-20 Stellen genau) -1,1x104932 bis +1,1x104932
char 1 Byte Buchstabe (positiver und negativer ASCII-Wert) -127 bis +127 (ASCII)
signed char 1 Byte Buchstabe (positiver und negativer ASCII-Wert) -127 bis +127 (ASCII)
unsigned char 1 Byte Buchstabe (positiver ASCII-Wert) 0 bis +255 (ASCII)
bool 1 Byte gibt true oder false zurück true (wahr) oder false (falsch)

Dienstag, 15. Mai 2012

Einführung in C++

C++ ist eine sogenannte "höhere Programmiersprache", welche 1979 von Bjarne Stroustrup entwickelt wurde. Der Vorgänger von C++ ist C; einer der größten Unterschiede zwischen beiden Sprachen ist, dass C++ objektorientierte Programmierung unterstützt. Demnach ist jedes C-Programm auch gleichzeitig mit C++ kompatibel.

C++ wurde ab 1979 immer weiterentwickelt und verbessert. Der aktuellste Standard ist C++11, welcher am 11.10.2011 veröffentlicht wurde. Aufgrung der Standardisierung der Sprache durch das American National Standards Institute (ANSI) ist die Portierung (z.B. von Windows auf Linux) von in C++ erstellten Programmen sehr viel einfacher, da sich die Compiler-Hersteller, wie beispielsweise Microsoft oder MinGW, an den ANSI-Standard halten müssen.

Ein weiterer Pluspunkt für C++ ist die Systemnähe, das bedeutet, dass C++ dem Programmierer einen großen Handlungsspielraum lässt. So kann man beispielsweise sogenannte Zeiger verwenden, welche dem Entwickler eine Menge Vorteile bringen (Mit ihnen ist es zum Beispiel möglich selber Speicher zu reservieren).

Außerdem ist C++ case-sensitive was bedeutet, dass auf Groß- und Kleinschreibung geachtet wird. Erstellt man beispielsweise die Funktion "Test()" kann man sie nicht mit "test()" oder "TEST()" aufrufen.

Dies war es auch schon zur Einführung in C++. Ich hoffe, ich konnte Ihnen die Sprache ein wenig näher bringen. Sollte es noch Fragen geben können Sie mir gerne eine E-Mail schreiben oder einen Kommentar posten.