Grundlagen

Programmierumgebung

Ein Projekt in VS anlegen

  • Datei \rightarrow Neu \rightarrow Projekt \rightarrow Andere Sprachen \rightarrow C++ \rightarrow Leeres Projekt
  • Neue Datei anlegen: Rechtklick auf das Projekt (nicht Solution) \rightarrow​ Hinzufügen \rightarrow​ Neues Element \rightarrow​ C++ Datei (oder anderer Gewünschter Typ)

Das Programmgerüst in C++

  • #include: Einbindung einer Bibliothek die das Programm um Funktionalitäten erweitert.
  • using namespace name: Festlegen eines Namensbereiches. name steht hierbei für eine Klasse aus einem #include.
  • int main() {}: Hauptfunktion/Einstiegsunkt jedes C++-Projektes. int ist der Return-Code/Exit-Status des Programmes.

Grundsätzliche Regeln beim Programmieren mit C++

  • Außer Präprozessor-Anweisungen werden alle C++-Befehle mit einem ; abgeschlossen werden.
  • Blöcke Umschließen einen Anweisungsblock sie werden mit {} gekenzeichnet. Das gängiste Format sind Funktionen: void name() {...}.
  • Klammern dürfen nur in Paaren vorkommen.
  • Formatierungen mit Leerzeichen und Tabulatoren werden vom Compiler ignoriert.

Projektdateien

Damit aus einer Quellcodedatei ein Programm wird sind mehrere Schritte notwendig in C++. Aufgrund das in größeren Projekten diese Schritte komplexer werden hat man sich Tools geschaffen, welche einem die Arbeit abnehmen diese komplexeren Befehle sich zu merken. Eine Toolsammlung die einem die Arbeit vereinfacht heißt kurz IDE (lang für Integrated Development Environment). In der Berufsschule verwenden wir MS Visual Studio, diese IDE (eine von vielen) legt Konfigurationsdateien an, um sich zu merken mit welchen Parametern diese Schritte durchgeführt werden.

  • Die Solution-Datei - *.sln: Über diese Datei wird die Solution geöffnet. Sie kann n Projekte enthalten und diese logisch miteinander in Verbindung setzen. Diese Datei wird geöffnet.
  • Die Projekt-Datei - *.vcxproj: Entscheidet über die Argumente die MSBuild übergeben werden und über sonstige spezielle Informationen die zum Projekt gespeichert werden.
  • Die Filterdatei - *.vcxproj.filters: Dient zur Gruppierung der Dateien im Solution Explorer in MS Visual Studio, da diese Struktur nicht der Ordnerstruktur entspricht.

Quelle: docs.microsoft.com

Kommentare in C++

Kommentare sind das wichtigste Hilfsmittel für das Verständnis von Quellcode. Sie dokumentieren den Code, da nach mehreren Tagen, Wochen oder Jahren der Gedanke, welcher zur Entstehung geführt hat, nicht mehr präsent ist. Oder es muss in einem kollaborativen Arbeitsumfeld ein Kollege am Code arbeiten, welcher den persönlichen Stil vom Autor nicht versteht.

Neben der absoluten Notwendigkeit zum grundlegenden Verständnis, machen Kommentare es auch bequemer und einfacher den Code zu verstehen. Dies führt zu einer höheren Effektivität.

In C++ gibt es zwei verschiedene Arten von Kommentaren. Einzeilige Kommentare und Mehrzeilige.

Mehrzeilige Kommentare Mehrzeilige Kommentare werden durch ein /* eingeleitet und enden mit einem */. Alles was zwischen diesen beiden Zeichenfolgen steht gilt als Kommentar.

int main()
{
    /* Variablendefinition */
    int a = 5;
    int b = 1;
    
    /*
    cout << "Dies wird nicht ausgeführt";
    
    cout << "Dies auch nicht!";
    */
    
    return 0;
}

Einzeilige Kommentare Einzeilige Kommentare werden durch ein // eingeleitet. Alles nach dieser Zeichenfolge gilt bis zum Ende der Zeile als Kommentar.

int main()
{
    // Variablendefintion
    int a = 5;
    int b = 1;
    
    //cout << "Dies wird nicht ausgeführt!";
    
    // Test wird ausgegeben!
    cout << "Test";
    
    // Aufpassen beim setzen von Kommentaren!
    cout << "Ausgegeben" // << "Nicht ausgegeben.";
                      //^ Syntaxfehler, da kein Semikolon!
    
    return 0;
}

Ausgaben in C++

C++ kann von sich aus keine Ausgaben generieren. Hierfür wird eine Bibliothek mit dem Namen iostream benötigt.

In C++ erweitern Bibliotheken die Funktionalitäten eines Programms, ohne das der Code hierfür zwangsweise vom Autor des Programms stammen muss. Andere Argumente und weiterführende Erklärungen sind bspw. hier zu finden: https://stackoverflow.com/a/10358977/4730773

Eine Bibliothek wird eingebunden mit folgenden Statements:

// Systembibliotheken
#include <Bibliothek>

// Lokale Dateien/Klassen/...
#include "Bibliothek"

Quelle: https://stackoverflow.com/a/21594/4730773

Für die Bibliothek für die Ein- und Ausgabe ergibt sich somit das Statement: #include <iostream>. Hierbei setzt sich der Name aus io und stream zusammen. IO steht für Input and Output was übersetzt Ein- und Ausgabe bedeutet. Streams sind Datenströme welche auf einem Ausgabegerät wie bspw. dem Bildschirm oder Drucker ausgegeben werden.

Für uns sind drei Dinge aus iostream besonders interessant: cout, cin und endl. Sie alle sind im Namespace std beheimatet. Ist dieser nicht eingebunden müssen diese Funktionen mit dem Präfix std:: aufgerufen werden.

  • std::cout: Ist verantwortlich für Ausgaben auf der Konsole. Es können ihm beliebig viele Parameter als Strings oder Chars übergeben werden die durch << miteinander verkettet worden sind. Dies können auch Rückgabewerte von Funktionen sein die zwischen zwei << aufgerufen worden sind.
  • std::cin: Soll in einem spätern Kapitel behandelt werden.
  • std::endl: Ist für einen Zeilenumbruch auf der Konsole verantwortlich.

Anmerkung: Strings werden in " eingeschlossen und Chars in '!

Variablen, EVA, Casting & Debugging

### Variablen

Um Daten zur Laufzeit eines Programms zu speichern, muss dem Computer dies mitgeteilt werden (es passiert nicht magisch). Erfährt der Computer, was und wie viel gespeichert wird, gibt dieser die Adresse zurück, unter der man den gewünschten Speicherplatz abrufen und benutzen kann. Beim Programmieren nennt man das Statement, mit dem Daten gespeichert werden können Variablen. Wird eine Variable deklariert, ist dem Computer bekannt das die Variable existieren wird (keine Reservierung von Speicher). Nun kann diese Variable definiert werden (Zuweisung von Speicher), d.h. ihr kann ein oder mehrere Werte zugewiesen werden von einem festgelegten Datentyp. Welche Werte gespeichert werden, hängt vom Datentyp der Variable ab, welcher im Programmcode festgelegt worden ist.

Eine Variablendefinition in C++ sieht folgendermaßen aus: int zahl;. Hierbei ist int der Datentyp, welcher eine positive und negative Ganzzahl darstellt. zahl stellt den Namen der Variable dar. In der Berufsschule benutzen wir die Hungarian Notation (siehe: http://web.mst.edu/~cpp/common/hungarian.html), heißt Variablennamen wird entsprechend ihrem Datentyp ein Präfix dem Namen hinzugegeben. Die Variable wird somit korrekt definiert mit int i_zahl;.

Die Initialisierung einer Variable sieht wie folgt aus: int i_zahl = 7;. Der Teil vor dem = ist die für uns bekannte Definition. Diese Initialisierung wird durch die Definition der Variable erweitert und die Variable i_zahl wird auf die Zahl 7 gesetzt.

Nachdem eine Variable Initialisiert und Definiert ist, kann sie zugewiesen werden. Dies sieht syntaktisch so aus: name = Wert;, in unserem Beispiel bedeutet das: i_zahl = -5;. Falls eine Variable nur initialisiert worden ist, hat sie ab nun einen definierten Wert. Hatte sie vorher bereits einen Wert, hat sich dieser nun geändert auf -5.

Um das Arbeiten mit Variablen zu erleichtern, ist es von Vorteil (und in der Berufsschule eine Programmierrichtlinie), dass man Variablen sprechende Namen gibt. Heißt Variablen sollten nicht a oder aa heißen, sondern stunden oder anzahlBaeume. Um möglichen Mitprogrammierern die Arbeit möglichst einfach zu machen, sollte man nur die Zeichen von A-Z, a-z und den _ verwenden. Andere Zeichen sind eventuell für die Syntax der Programmiersprache reserviert oder nicht im lokalen Zeichensatz auf der Tastatur des Landes vertreten.

Was von geringerer Relevanz ist für die jetzigen Themen, später jedoch schon, ist die reine Variablendeklaration. Sie sagt dem Compiler, es wird zur Laufzeit eine Variable vom Typ X mit Namen Y existieren. Um dem Compiler dies zu zeigen, gibt es das Schlüsselwort extern. Dies bedeutet, wenn man im Programm einen Variablennamen benutzen möchte, welcher außerhalb definiert bzw. initialisiert wird, sieht das folgendermaßen aus: extern int i_zahl;.

Wertebereiche von Variablen

C++ Datentyp beinhaltet Minimum/kleinster Wert Maximum/größter Wert Speicherplatz
bool (Boolean) true (1) oder false (0) 0 (false) 1 (true) 8 Bit, 1 Byte
char Zeichen (Character) -128 +127 8 Bit, 1 Byte
unsigned char pos. Ganzzahl 0 +255 8 Bit, 1 Byte
int pos. und neg. Ganzzahl -32.768 +32.767 16 Bit, 2 Byte
unsigned int pos. Ganzzahl 0 +65.535 16 Bit, 2 Byte
int pos. und neg. Ganzzahl -2.147.483.648 +2.147.483.647 32 Bit, 4 Byte
unsigned int pos. Ganzzahl 0 +4.294.967.295 32 Bit, 4 Byte
int pos. und neg. Ganzzahl -9.223.372.036.854.775.808 +9.223.372.036.854.775.807 64 Bit, 8 Byte
unsigned int pos. Ganzzahl 0 +18.446.744.073.709.551.615 64 Bit, 8 Byte
short pos. und neg. Ganzzahl -32.768 +32.767 16 Bit, 2 Byte
unsigned short pos. Ganzzahl 0 +65.535 16 Bit, 2 Byte
long pos. und neg. Ganzzahl -2.147.483.648 +2.147.483.647 32 Bit, 4 Byte
unsigned long pos. Ganzzahl 0 +4.294.967.295 32 Bit, 4 Byte
long long pos. und neg. Ganzzahl -9.223.372.036.854.775.808 +9.223.372.036.854.775.807 64 Bit, 8 Byte
unsigned long long pos. Ganzzahl 0 +18.446.744.073.709.551.615 64 Bit, 8 Byte
float Gleitkommazahl (6 Stellen) -3,4E+38 +3,4E+38 32 Bit, 4 Byte
double genauere Gleitkommazahl (15 Stellen) -1,7E+308 +1,7E+308 64 Bit, 8 Byte
long double noch genauere Gleitkommazahl (18 Stellen) -1,1E+4932 +1,1E+4932 80 Bit, 10 Byte

Einlesen von Werten mit std::cin

Um Werte von einem Konsolenfenster einzulesen und in einer Variable zu speichern, wird aus der Bibliothek iostream im Namespace std die Funktion cin bereitgestellt. Die Syntax der Funktion ist wie folgt: std::cin >> i_Eingabe. Die Eingabe im Konsolenfenster muss mit der Enter-Taste bestätigt werden. Der Benutzer des Programms erkennt, dass das Programm auf seine Eingabe wartet, indem der Cursor der Konsole blinkt. Mit cin kann nur ein Wert auf einmal eingelesen werden, dies steht gegensätzlich zum Verhalten von cout, welches mit einem weiteren << Operator eine weitere Ausgabe übergeben bekommen kann.

EVA-Prinzip

Eingabe $\rightarrow$ Verarbeitung $\rightarrow$ Ausgabe

Das Prinzip nimmt sich als Vorbild das menschliche Denken: Eine Information wird wahrgenommen $\rightarrow$ Sie wird verarbeitet $\rightarrow$ Es wird auf die Information reagiert. Ein Beispiel wäre eine Unterhaltung, bei der jeder Gesprächspartner über die Antwort des anderen Nachdenkt und schließlich antwortet.

// Anmerkung dieses Programm dient zur Demonstration, mir ist bewusst, dass im Jahr 2020 falsche Ergebnisse herauskommen.
int main()
{
    // Defintion der Variablen
    unsigned int i_alter = 0;
    long l_geburtsjahr = 0;
    
    // Eingabe
    std::cout << "Bitte gebe dein Alter ein: ";
    std::cin >> i_alter;
    
    // Verarbeitung
    l_geburtsjahr = 2019 - i_alter;
    
    // Ausgabe
    std::cout << "Dein Geburtsjahr ist: " << l_geburtsjahr;
    
    // Ein erfolgreiches Programmende wird mit dem Rückgabewert 0 an das Betriebssystem gemeldet.
    return 0;
}

In der Berufsschule gilt, dass bei allen Aufgaben nach Möglichkeit das EVA-Prinzip angewandt wird!

Casting

Es gibt zwei Sorten von Typumwandlungen: Automatische (Implicit) und Erzwungene (Explicit) Typumwandlungen (Castings).

Automatische Typumwandlungen:

int i_zahl1 = 5;
float f_zahl2 = 7.5;
double d_zahl3 = 10.3;

ergebnis = i_zahl1 * f_zahl2; // Ergebnis: 37.5 Typ: float
ergebnis = f_zahl2 * d_zahl3; // Ergebnis: 17,8 Typ: double

Erzwungene Typumwandlung

int i_zahl1 = 12;
int i_zahl2 = 6;
f_Ergebnis = (float) i_zahl1 / i_zahl2; // Ergebnis: 2.0 Typ: float

Debugging

Es gibt genügend Tutorials, welche Debugging gut erklären. Hier für Visual Studio 2017 ein paar Links zur offiziellen Dokumentation:

Konstanten

Konstanten sind Werte, die extrem schnell für den Computer verfügbar sind, weil der Compiler diese extra bereithält. Sie haben jedoch den Nachteil, dass sie unveränderbar sind. Als Beispiel kann eine ASCII-Tabelle dienen, die Zeichen der Tabelle sind einzeln definiert und somit extrem schnell verfügbar, bei der Ausführung eines Programms.