Präprozessors Befehl
include ist kein direkter Bestandteil der Sprache C, sondern ein Befehl des Präprozessors. Präprozessor ist ein Teil des Compilers. Präprozessorbefehle erkennen Sie am vorangestellten #-Zeichen. include-Dateien nennt man auch Headerdateien.
#include <stdio> // Standard-Input/Output.
Header nach Kategorie
| Category | Header |
|---|---|
| Algorithmen | <algorithm>, <cstdlib>, <numeric> |
| Atomvorgänge | <atomic>11 |
| C-Bibliotheksumbruch | <cassert>, <ccomplex> 11a b,<ciso646><climits><csignal><cmath><cfenv><cerrno><clocale><csetjmp><cinttypes><cfloat><cctype><cstdalign> 11, 11, b, 11<cstdarg><cstdbool> a b, 11 a b, 11 b<cstddef><cuchar><cstdint><cstdlib><cwchar><cstdio><cstring><ctgmath><ctime>, , 11, 11 a, , 11,<cwctype> |
| Konzepte | <concepts>20 |
| Container | |
| Sequenzcontainer | <array>11, , 11, <list><deque>, <forward_list><vector> |
| Bestellte assoziative Container | <map>, <set> |
| Nicht sortierte zuordnende Container | <unordered_map>11, <unordered_set>11 |
| Containeradapter | <queue>, <stack> |
| Containeransichten | <span>20 |
| Fehler und Ausnahmebehandlung | <cassert>, <exception><stdexcept><system_error>11 |
| Allgemeine Dienstprogramme | <any>17<bit>, 20,<cstdlib><bitset><execution>17, <memory_resource><functional><memory>17, <optional> 17, <tuple><scoped_allocator><ratio><typeindex><utility><type_traits><variant> 11, 11, 11, 11, 11, 11, , 17 |
| I/O und Formatierung | <cinttypes>11, , <filesystem>17, <fstream><ios><streambuf><iosfwd><cstdio><ostream><sstream><strstream><istream><iomanip><iostream>c,<syncstream>20 |
| Iterators | <iterator> |
| Sprachunterstützung | <cfloat><climits>, , <codecvt>11 a, <compare>20,<contract>20, <coroutine>20, 11, <cstdlib><initializer_list><exception>11, <limits><new><version><typeinfo>11 , 20<csetjmp><csignal><cstdarg><cstddef><cstdint> |
| Lokalisierung | <clocale>, <codecvt>11 a, , <cvt/wbuffer>, <cvt/wstring><locale> |
| Mathematik und Numerische | <bit>20, <cfenv>11, <cmath>, <limits><cstdlib><numeric><complex><random> 11, <ratio> 11,<valarray> |
| Speicherverwaltung | <allocators><memory>, <memory_resource>17, , <new><scoped_allocator>11 |
| Multithreading | <atomic>11,<condition_variable> 11, <mutex><future>11, 11, 14, <thread><shared_mutex>11 |
| Bereiche | <ranges>20 |
| Reguläre Ausdrücke | <regex>11 |
| Zeichenfolgen und Zeichendaten | <charconv>17, , <cstdlib><cuchar><cstring>11, <cctype>, 11<regex><cwctype><cwchar>, <string>,<string_view> 17 |
| Time | <chrono>11, <ctime> |
int main()
Hier beginnt das Hauptprogramm. Eine main-Funktion wird immer benötigt, damit der Compiler weiss, wo er beginnen muss, das Programm zu übersetzen. (Hauptfunktion). int steht für eine Ganzzahl. (Für Funktionen mit Rückgabewert)
Das void in der main()-Funktion steht für einen »leeren« Datentyp.
return 0;
Das bedeutet: Das Programm wurde ordnungsgemäss beendet
{ printf("….."); }
Zwischen den geschweiften Klammern steht unser Anweisungsblock. Geschweifte Klammern fassen Anweisungen zu einem Block zusammen.
Semikolon (;)
Es wird hauptsächlich dazu verwendet, das Ende einer Anweisung anzuzeigen. Der Compiler weiss dann, dass hier das Ende der Anweisung ist Fährt dann nach der Abarbeitung der Anweisung mit der nächsten Zeile fort.
Vergleichsoperationen
| Operator | Bedeutung |
|---|---|
| a < b | ist Wahr, wenn a kleiner b ist |
| a > b | ist Wahr, wenn a grösser b ist |
| a <= b | ist Wahr, wenn a kleiner oder gleich b ist |
| a >= b | ist Wahr, wenn a grösser oder gleich b ist |
| a == b | ist wahr, wenn a gleich b ist |
Umlaute
Wenn Sie in C oder C++ Umlaute schreiben, kommen meistens irgendwelche komischen Zeichen heraus, aber nicht die Umlaute. Sie haben schon mal von der hexadezimalen Darstellung gehört. Hier werden die Umlaute einfach hexadezimal ausgegeben.
Umlaute Hexadezimal:
| Umlaute | Hex |
|---|---|
| ä | x84 ist nur die Schreibweise für hexadezimale Zahlen |
| ö | x94 |
| ü | x81 |
| Ä | x8E |
| Ü | x99 |
| ß | xE1 |
Bei der Zeichenkodierung verwendete ASCII-Code streng genommen nur 128 Zeichen (Codes 0 bis 127). Für die obere Hälfte der ASCII-Tabelle (Codes 128 -255) gibt es verschiedene Erweiterungen. Leider befinden sich die deutschen Umlaute in der oberen Hälfte und sind somit nicht einheitlich genormt.
Bei Windows-Programmen wird im Konsolenfenster standardmässig die Erweiterung “Code Page 850” verwendet, im Programm-Editor aber eine andere. Dies bewirkt, dass im Editor eingegebene Umlaute im Konsolenfenster falsch dargestellt werden. Unter Windows besteht jedoch die Möglichkeit,die Konsole auf “Code Page 1250 oder 1252” umzustellen, was kompatibel zum Editor ist. Diese Einstellung kann man sowohl für die Eingabe als auch für die Ausgabe vornehmen. Man muss dazu die beiden folgenden Anweisungen in den Quelltext, in der Regel in die main()-Funktion, einsetzen:
SetConsoleOutputCP (1250);// Für die Umlaut-Ausgabe
SetConsoleCP (1250);// Für die Umlaut-Eingabe
Alternativ kann man auch
system("chcp 1250");
für Ein-und Ausgabe verwenden. Allerdings gibt das System dann eine unerwünschte Meldung aus.In jedem Fall muss die Datei <windows.h> eingebunden werden. Das nachfolgende Beispielprogramm zeigt die Vorgehensweise:
#include <iostream>
#include <cstdio>
#include <windows.h>
using namespace std;
int main() {
char input;
// Windows code page 1250 / 1252 oder 28591 entspricht ISO-Latin-1
SetConsoleOutputCP (1250);
SetConsoleCP (1250);
cout << endl << " Ausgabe von Umlauten unter C++";
cout << endl << " Und jetzt geht es: ä ö ü Ä Ö Ü $" << endl << endl;
do {
cout << " Ihr Zeichen (0=Ende) >";
cin >> input;
cout << " " << input << endl;
}while(input != '0');
return 0;
}
Schlüsselwörter
Die Schlüsselwörter der Programmiersprache C/C++. Diese Schlüsselwörter sollten für Variablen-Namen nie verwendet werden:
- asm
- auto
- break
- case
- char
- const
- continue
- default
- do
- double
- else
- enum
- extern
- float
- for
- goto
- if
- int
- long
- register
- return
- short
- signed
- sizeof
- static
- struct
- switch
- typedef
- union
- unsigned
- void
- volatile
- while
Logische Operatoren
Mit der Negation wird ein Wert invertiert, also umgekehrt. D.h. aus wahr wird falsch und aus falsch wird wahr. Die Negation erreichen wir mit einem einfachen Ausführungszeichen “!”.
int a=5;
if(!0) cout << "aus falsch wird wahr, 0 -> 1\n";
if(!a) cout << "aus wahr wird falsch, 5 -> 0\n";
&&
Mit dem logischen UND && prüfen wir ob mehrere Bedingungen erfüllt sind.
||
Muss nur eine von mehreren Bedingungen erfüllt sein
Zeichensatz
Basic-Zeichensatz:
- Der Basic-Zeichensatz beinhaltet Zeichen für den Quellcode. (Dezimalzahlen, Alphabet, einige Sonderzeichen -> ! " % & / ( ) [ ] { } \ ? =’ # + * ~ – _ . : ; , | < > ^)
Ausführungszeichensatz:
- Der Ausführungszeichensatz enthält Zeichen, die erst bei der Ausführung des Programms interpretiert werden. (Steuerzeichen, Umlaute, usw.)
Beim Ausführungszeichensatz kommen zu den oben aufgeführten Zeichen noch weitere hinzu.
Steuerzeichen (Escape-Sequenzen) in Zeichenkonstanten
Steuerzeichen sind nicht druckbare Zeichen. Sie können damit die Ausgabe auf dem Bildschirm beeinflussen. Steuerzeichen beginnen also immer mit einem Backslash ( \ ), auf den eine Konstante folgt.
| Value | Escape sequence |
|---|---|
| newline | \n |
| backslash | \\ |
| horizontal tab | |
| question mark | ? or \? |
| vertical tab | \v |
| single quote | \' |
| backspace | \b |
| double quote | \" |
| carriage return | \r |
| the null character | \0 |
| form feed | \f |
| octal | \ooo |
| alert (bell) | \a |
| hexadecimal | \xhhh |
ASCII-Tabelle
| Character | Character Name | ASCII code |
|---|---|---|
| ! | Exclamation point | 33 |
| “ | Double quotation | 34 |
| # | Number sign | 35 |
| $ | Dollar sign | 36 |
| % | Percent sign | 37 |
| & | ampersand | 38 |
| ‘ | apostrophe | 39 |
| ( | Left parenthesis | 40 |
| ) | Right parenthesis | 41 |
| * | asterisk | 42 |
| + | Plus sign | 43 |
| , | comma | 44 |
| – | hyphen | 45 |
| . | period | 46 |
| / | slash | 47 |
| 0 | zero | 48 |
| 1 | one | 49 |
| 2 | two | 50 |
| 3 | three | 51 |
| 4 | four | 52 |
| 5 | five | 53 |
| 6 | six | 54 |
| 7 | seven | 55 |
| 8 | eight | 56 |
| 9 | nine | 57 |
| : | colon | 58 |
| ; | semi-colon | 59 |
| < | Less-than sign | 60 |
| = | Equals sign | 61 |
| > | Greater-than sign | 62 |
| ? | Question mark | 63 |
| @ | At sign | 64 |
| A | Uppercase a | 65 |
| B | Uppercase b | 66 |
| C | Uppercase c | 67 |
| D | Uppercase d | 68 |
| E | Uppercase e | 69 |
| F | Uppercase f | 70 |
| G | Uppercase g | 71 |
| H | Uppercase h | 72 |
| I | Uppercase i | 73 |
| J | Uppercase j | 74 |
| K | Uppercase k | 75 |
| L | Uppercase l | 76 |
| M | Uppercase m | 77 |
| N | Uppercase n | 78 |
| O | Uppercase o | 79 |
| P | Uppercase p | 80 |
| Q | Uppercase q | 81 |
| R | Uppercase r | 82 |
| S | uppercases | 83 |
| T | Uppercase t | 84 |
| U | Uppercase u | 85 |
| V | Uppercase v | 86 |
| W | Uppercase w | 87 |
| X | Uppercase x | 88 |
| Y | Uppercase y | 89 |
| Z | Uppercase z | 90 |
| [ | Left square bracket | 91 |
| \ | backslash | 92 |
| ] | Right square bracket | 93 |
| ^ | caret | 94 |
| _ | underscore | 95 |
| ` | Grave accent | 96 |
| a | Lowercase a | 97 |
| b | Lowercase b | 98 |
| c | Lowercase c | 99 |
| d | Lowercase d | 100 |
| e | Lowercase e | 101 |
| f | Lowercase f | 102 |
| g | Lowercase g | 103 |
| h | Lowercase h | 104 |
| i | Lowercase i | 105 |
| j | Lowercase j | 106 |
| k | Lowercase k | 107 |
| l | Lowercase l | 108 |
| m | Lowercase m | 109 |
| n | Lowercase n | 110 |
| o | Lowercase o | 111 |
| p | Lowercase p | 112 |
| q | Lowercase q | 113 |
| r | Lowercase r | 114 |
| s | Lowercase s | 115 |
| t | Lowercase t | 116 |
| u | Lowercase u | 117 |
| v | Lowercase v | 118 |
| w | Lowercase w | 119 |
| x | Lowercase x | 120 |
| y | Lowercase y | 121 |
| z | Lowercase z | 122 |
| { | Left curly brace | 123 |
| | | Vertical bar | 124 |
| } | Right curly brace | 125 |
| ~ | tilde | 126 |
Rechenoperatoren
Variablen und Konstanten können durch Rechenoperatoren miteinander verknüpft und einer neuen Variablen zugeordnet werden.
Als Klammern sind in Ausdrücken nur runde Klammern erlaubt. Sie bewirken, dass der darin enthaltene Ausdruck zuerst berechnet wird. Nach Ausführung der Klammerausdrücke führt der Compiler die Operationen von links nach rechts aus.
| Operator | Math. ausdruck |
|---|---|
| + | Addition |
| - | Subtraktion |
| * | Multiplikation |
| / | Division |
| % | Restdivion (Modulo) |
double x = 6(4 + 7.4)2; //falsch
double y = 5 * (4 + 7.4) * 2; // ok
Ein- und Ausgaberoutinen
Ein- und Ausgaberoutinen geben Ihnen die Möglichkeit, mit einem Programm zu interagieren.
Um die C++ Ein- und Ausgabe nutzen zu können, müssen Sie die Bibliothek “iostream” einbinden.
Um diese “Ein- und Ausgaberoutinen” im Programm nutzen zu können, geben Sie dem Compiler bekannt: using namespace std.
Das Teilt dem Compiler mit das dieser Befehl in einem speziellen Namensraum befindet.
Der Namensraum „std“ heisst so viel wie Standard. Wenn etwas in diesem Namensraum steht, dann gehört es zur C++-Standardbibliothek und die sollten
Sie (in der Regel) wann immer möglich einsetzen.
Formatierte Ausgabe mit Manipulatoren
Um Informationen besser formatieren zu können, stellt C++ eine Reihe von Manipulatorenzur Verfügung. Viele Dieser Manipulatoren werden durch die Headerdatei “iomanip” eingebunden.
| Manipulator | Bedeutung |
|---|---|
| setw(int n) | Festlegung der Feldbreite |
| setfill(char) | Festlegung des Füllzeichens |
| left | Linksbündig |
| right | rechtsbündig |
| scientific | Exponentendarstellung |
| fixed | Gleitpunktdarstellung |
| showpos | Anzeige des positiven Vorzeichens |
| uppercase | Grossbuchstaben |
| setprecision(int n) | Anzahl der Nachkommastellen |
| dec, hex, oct | Umwandlung in andere Zahlensysteme |
Inkrement & Dekrement
Wollen wir den Wert einer Variablen um eins erhöhen oder erniedrigen, empfiehlt es sich die Inkrement- und Dekrement-Operatoren zu nutzen.
Zeichen: ++ oder –
bsp.
// mit Inkrement-Operator
int a=0, b=0;
a++;
b--;
// ohne Inkrement-Operator
a = a + 1;
b = b – 1;
Achtung bei der Zuweisung
Bei der Zuweisung gibt es mit ++ und – noch eine Besonderheit:
int a, b=0;
// Erst Zuweisung, dann Inkrement
a = b++;
// Erst Inkrement, dann Zuweisung
a = ++b;
Präfix und Postfix
Der Inkrementoperator und der Dekrementoperator existieren in zwei Spielarten:
Präfix und Postfix.
Präfix ++counter –counter Inkrementiere den Wert zuerst und übertrage in dann.
Postfix counter– counter++ Übertrage den Wert zuerstund inkrementiere dann.
Deklaration von Variablen
Mit der Deklaration benennen wir eine Variable. Unter der Definition versteht man, dass einer Variablen ein Speicherbereich zugeteilt wird. Haben wir eine Variable deklariert und definiert, so hat sie einen beliebigen Wert - je nach dem was gerade im zugewiesenen Speicherbereich steht.
Bsp. int zahl; oder int a, b, c;
Variablen
Variablen einführen
Wenn eine Variable das erste Mal verwendet wird, muss ihr Name und der Datentyp dem Compiler bekannt gegeben werden. Diesen Vorgang nennt man Variablenvereinbarung.
Werte zuweisen
Unter dem Namen einer eingeführten Variablen können bestimmte Werte abgespeichert werden.
Wertzuweisungen bestehen normalerweise aus der Variablen selbst (sie muss immer links stehen) einer Zahl oder einem Ausdruck (rechts von der Variablen).
Regeln
Ein Name darf Buchstaben, Zahlen und das Zeichen _ (englisch: «underline») enthalten, jedoch keine Zwischenräume und keine Sonderzeichen. Das erste Zeichen muss ein Buchstabe oder ein Underline sein.
Variablen sind Case sensitiv (Es wird zwischen Gross- und Kleinschreibung unterschieden. Eine Variable sollte also immer richtig geschrieben werden sonst gibt es Probleme.)
Variable_1 //ok
Heute Morgen //nicht erlaubt: Zwichenraum
vater&söhne //nicht erlaubt: Sonderzeichen
3_laender //nicht erlaubt: Zahl am anfang
int //nicht erlaubt: bereits für Datentyp besetzt
_int //erlaubt, aber nicht empfohlen (wird normalerweise für Systemfunktionen verwenden)
double z; //z als Flieskommazahl vereinbart
int zahl; //zahl als Ganzkommazahl
char zeichen; //Zeichenvariable
bool zustand; //Zustandsvariable
float z; //korrekt, z als float vereinbart,
z = 46.3; //dann eine Wertzuweisung
int x = 347; //ok. Vereinbarung der Variablen. x und Wertzuweisung kombiniert
220.7= double z; //falsch. Zahl muss rechts stehen
int x = 2; //ok.
int z = 25*x + 5; //Wertzuweisungen können auch Ausdrücke (Formeln) sein
Variablen ausgeben
Bildschirmausgaben
printf("Hello World");
Ausgabe von Variablen
Wollen wir in den auszugebenden Text Variablenwerte einfügen, geht dies mit der Formatierungsanweisung %. Für jeden Datentyp gibt es einen eigenen Formatierungstyp. Die Formatierungsanweisung wird in den Text geschrieben, also zwischen die “ “. Danach folgen die Variablennamen nach dem Komma.
Ausgabe von Zeichen
Für die Ausgabe eines einzelnen Zeichens verwenden wir den Formatierungstyp %c.
bsp.:
char vari = ‘Z';
printf("Das Alphabet endet mit: %c", vari);
Der Formatierungstyp für ganze Zahlen ist %d. (Merke: Dezimalwerte)
bsp.:
int laenge=312500, breite=50;
printf("\nLaenge: %d cm\nBreite: %d cm\n", laenge, breite);
printf("\nLaenge: %10d cm\nBreite: %10d cm\n", laenge, breite);
Zur Ausgabe von Kommazahlen verwenden wir den Formatierungstyp %f.
So wie man den Vorkommateil auf eine bestimmte Länge bringen kann, kann man dies auch mit dem Nachkommateil machen. Mit %2.3f hat man z.B. 2 Vorkomma-stellen und 3 Nachkommastellen. Was zu wenig ist, wird aufgefüllt - was zu viel ist, wird abgeschnitten.
Sollen beim Auffüllen keine Leerzeichen, sondern führende Nullen verwendet werden, erreichen wir dies mit einer Null nach %, also %0.
bsp.:
int tag=3, monat=9, jahr=2007;
printf("Ein Datum: %02d.%02d.%4d\n", tag, monat, jahr);
Tastatureingaben
Zeichen einlesen mit getchar
char c;
printf("Mit welchem Buchstaben beginnt ihr Vorname? ");c = getchar();
printf("\nIch weiss jetzt, dass Ihr Vorname mit %c beginnt.\n", c);
//Oder mit C++
cout << “Dein Vorname beginnt mit : “ << c << “\n“;
Zahlen einlesen
int alter;
printf("Wie alt sind sie? ");
scanf("%d", &alter);
printf("\nIn %d Jahren sind Sie 100!\n", 100-alter);
//Oder mit C++
cin >> alter;
Datentyp wechseln
Oft möchte man z. B. eine Dezimalzahl in eine Ganzzahl umformen. Man nennt dies Typumwandlung.
Umgekehrt kann aber eine Fliesskommazahl nicht einem Ganzzahltyp zugeordnet werden. Da auf diese Weise ein Teil der Zahl verloren geht.
Es muss mittels «type casting» die Umwandlung erzwungen werden.
Konstanten
Konstanten werden durch das Wort const gekennzeichnet. Üblicherweise werden bei den Namen der Konstanten Grossbuchstaben verwendet. Der Wert muss immer sofort zugewiesen werden. Bei “const” bleibt die Variable immer gleich und kann nicht durch eine Rechenoperation oder anderes verändert werden.
const int "Variable" = 25
//bsp.
const double PI = 3.14159; //ok
const double MEHRWERTSTEUER = 0.075; //ok. Prozent gibt es nicht in C
const float UMRECHNUNGSKURS; //falsch: Wert muss sofort zugewiesen werden
Schleifen, Verzweigungen, Sprünge
Verzweigungen:
Hierbei wird im Programm eine Bedingung definiert. Je nachdem, ob diese wahr oder nicht wahr ist, wird das Programm an unterschiedlichen Stellen fortgesetzt.
if(Bedingung)
{
Anweisung(en);
} else
{
Falls Bedingung nicht zutrifft
}
bzw.
switch-Verzweigung
switch(Ausdruck)
{
case Ausdruck1 : Anweisung(en);
break;
case Ausdruck2 : Anweisung(en);
break;
case Ausdruck3 : Anweisung(en);
break;
default : Anweisung(en);
}
Mit break wird die Verzweigung beendet. default gleicht der else Funktion.
Schleifen:
Sie sind dazu da, Anweisungen zu wiederholen bis die Bedingung erfüllt wird. Eine Schleife verwenden wir, um Wiederholungen im Programm zu realisieren - also um Dinge mehrmals zu machen. Jede Schleife hat eine Durchlauf-Bedingung, damit sie nicht endlos läuft.
while Schleife
while(Bedingung)
{
Anweisung(en);
}
for Schleife Die for Schleife verwenden wir, wenn die Anzahl der Durchläufe bekannt ist. D.h. es ist eine Zähler-gesteuerte Schleife Wir benötigen also immer eine Variable, welche wir zum Zählen der Durchläufe verwenden.
int i;
for(i=0; i<5; i++) {
cout << "Zahl " << i+1 << "\n";
}
- Bereich 1: Startwert der Zählvariablen setzen, z.B. i=0
- Bereich 2: Durchlauf-Bedingung, z.B. i<5
- Bereich 3: Operation auf Zählvariable ausführen, z.B. i++
for-each
Mit der for-Schleife muss immer auf die korrekte Zählweise geachtet werden. Also nicht kleiner als 0 und auch nicht die Listengrösse übersteigen
Eine Variante der for-Schleife, die Ihnen diese ganze Index-Problematik abnimmt und daher zur Vermeidung von Programmierfehlern oft die bessere Wahl ist, ist die sogenannte for-each-Schleife. For-each bedeutet »Für jedes«, also: für jedes Element der Liste mache etwas Bestimmtes.
For-each hat also eine Variable, die das jeweilige Element enthält und die nach jedem Durchgang auf das nächste Element gesetzt wird. Sie müssen also nicht mit Zahlen hantieren, sondern können direkt mit den Elementen arbeiten.
vector<int> vec={11,22,33,44,55,66};
cout<<"The elements are: ";
for(auto var : vec) {
cout<<var<<" ";
}
Sprünge:
Die Programmausführung wird unterbrochen und an einer bestimmten Stelle, die markiert wurde, fortgesetzt.
Schleifen-Verschachtelung
Schleifen können auch beliebig verschachtelt werden. Es gibt eine äussere Schleife und eine inneren Schleife. Die Durchlauf-Bedingung der inneren Schleife ist meist an die äussere Schleife gebunden.
kopfgesteuerte Schleifen// fussgesteuerte Schleifen
while und for sind sogenannte kopfgesteuerte Schleifen. D.h., dass der Kontrollpunkt als erstes vor jedem Durchlauf ausgeführt wird. Soll zuerst der Schleifen-Block ausgeführt und dann die Bedingung für einen erneuten Durchlauf geprüft werden, verwenden wir die do while Schleife. Diese ist also eine fussgesteuerte Schleife.
int alter;
do
{
cout << "\nBitte geben sie ihr Alter ein: ");
cin >> alter;} while(alter < 18);
cout << "Danke. Hier dein Bier. Prost!\n");
}while
break//continue
Mit dem Schlüsselwort break können wir zu jeder Zeit auch eine Schleife verlassen, ohne auf den Kontrollpunkt warten zu müssen.
bsp.:
int Zahl = 17;
while(Zahl >= 3)
{
cout << "Die Zahl ist \a" << Zahl << endl;
if(Zahl == 9)
{
cout << "Es gabe einen Fehler in der Matrix" << endl;
break;
}
Zahl--;
}
cout << endl;
system("PAUSE");
return 0;
Mit dem Schlüsselwort continue haben wir die Möglichkeit, direkt zum Kontrollpunkt zu springen. Somit wird der restliche Code im Schleifen-Block nicht ausgeführt.
bsp.:
int Minimum;
int Maximum;
int teiler;
cout << "\nBitte geben Sie die höchste Zahl ein > ";
cin >> Maximum;
cout << "\nBitte geben Sie die niedrigste Zahl ein > ";
cin >> Minimum;
cout << "\nBitte geben Sie den Teiler ein > ";
cin >> teiler;
cout << endl << "___________________________________" << endl << endl;
int counter;
for(counter = Minimum; counter <= Maximum; counter++) {
if(counter == 42)
{
cout << "Die antwort die Grosse Frage. Nach dem Leben, dem Universum und allem lautet: 42" << endl;
continue;
}
if (counter % teiler == 0)
{
cout << counter << endl;
}
}
Sprünge:
Die Programmausführung wird unterbrochen und an einer bestimmten Stelle, die markiert wurde, fortgesetzt
Trigraph-Zeichen
Als Trigraph bezeichnet man in der Linguistik eine Kombination aus drei Schriftzeichen.
Bei der Entwicklung neuer Software sollten Sie, wenn möglich, auf den Einsatz von Trigraph-Zeichen komplett verzichten.
| Trigraph | Interpunktionszeichen |
|---|---|
| ??= | # |
| ??( | [ |
| ??/ | \ |
| ??) | ] |
| ??' | ^ |
| ??< | { |
| ??! | \ |
| ??> | } |
| ??- | ~ |
Datentypen
Bei der Wahl des richtigen Datentyps spielen folgende Überlegungen eine wichtige Rolle:
- Was möchte ich speichern oder verarbeiten?
- Zeichen, Text, Zahl oder Kommazahl
- Char, String, Int, float etc.
| Typname | Byte | Andere Namen | Wertebereich |
|---|---|---|---|
| int | 4 | signed | -2,147,483,648 bis 2,147,483,647 |
| unsigned int | 4 | unsigned | 0 bis 4.294.967.295 |
| __int8 | 1 | char | –128 bis 127 |
| unsigned __int8 | 1 | unsigned char | 0 bis 255 |
| __int16 | 2 | short, short int, signed short int | –32.768 bis 32.767 |
| unsigned __int16 | 2 | unsigned short, unsigned short int | 0 bis 65.535 |
| __int32 | 4 | signed, signed int, int | -2,147,483,648 bis 2,147,483,647 |
| unsigned __int32 | 4 | unsigned, unsigned int | 0 bis 4.294.967.295 |
| __int64 | 8 | long long, signed long long | -9,223,372,036,854,775,808 bis 9,223,372,036,854,775,807 |
| unsigned __int64 | 8 | unsigned long long | 0 bis 18.446.744.073.709.551.615 |
| bool | 1 | none | false oder true |
| char | 1 | none | -128 bis 127 standardmäßig 0 bis 255, wenn sie mithilfe kompiliert werden /J |
| signed char | 1 | none | –128 bis 127 |
| unsigned char | 1 | none | 0 bis 255 |
| short | 2 | short int, signed short int | –32.768 bis 32.767 |
| unsigned short | 2 | unsigned short int | 0 bis 65.535 |
| long | 4 | long int, signed long int | -2,147,483,648 bis 2,147,483,647 |
| unsigned long | 4 | unsigned long int | 0 bis 4.294.967.295 |
| long long | 8 | keine (aber gleichwertig mit __int64) | -9,223,372,036,854,775,808 bis 9,223,372,036,854,775,807 |
| unsigned long long | 8 | keine (aber gleichwertig mit unsigned __int64) | 0 bis 18.446.744.073.709.551.615 |
| enum | Variiert | none | |
| float | 4 | none | 3.4E +/- 38 (7 Stellen) |
| double | 8 | none | 1.7E +/- 308 (15 Stellen) |
| long double | gleiches wie double | none | Identisch mit double |
| wchar_t | 2 | __wchar_t | 0 bis 65.535 |
bsp. (string und char):
int main() {
char text[20]="Blabla";
cout << "hallo char möchte gerne etwas ausgeben " << text << endl;
system("PAUSE");
return 0;
}
bsp. (bool):
using namespace std;
int main() {
int x;
bool Variable = (x == 2);
if(Variable)
{
cout << "Fehler in der Matrix :-)\n";
}
else
{
cout << "lol";
}
system("PAUSE")
return 0;
}
Deklaration, Definition und Initialisierung
Mit der Deklaration benennen wir eine Variable. Unter der Definition versteht man, dass einer Variablen ein Speicherbereich zugeteilt wird. Haben wir eine Variable deklariert und definiert, so hat sie einen beliebigen Wert - je nach dem was gerade im zugewiesenen Speicherbereich steht
Vector & Strings
Mit den Klassen vector und string stehen dir eine Menge nützlicher Funktionalitäten zur Verfügung, die du von einem Array bzw. String erwarten darfst. Reservieren von weiterem Speicher musst du dir keine Gedanken machen. Pufferüberläufe können ebenfalls abgefangen werden.
Vector
Für Arrays empfehlen die C++-Doktoren die Klasse vector.
Um die Klasse verwenden zu können, musst du die gleichnamige Headerdatei “vector” mit einbinden.
#include < vector >
Ein vector ist im Wesentlichen ein dynamisches Feld, das je nach Bedarf seine Grösse dynamisch verändern kann. Auf ein beliebiges Objekt innerhalb des Feldes kann sehr effizient unter direkter Adressierung zugegriffen.
Syntax
vector< int > meinvecray(5);
Hinweis: Alle Elemente werden gleich mit der Zahl 0 initialisiert. Den Zugriff auf die einzelnen Elemente des Arrays kannst du wieder über die eckigen Klammern [n] realisieren.
Containerklassen
Sequentielle Containerklassen
- vector
- deque
- list
Container sind Behälter für Objekte. Dabei wird immer eine Kopie des Objektes in dem Container gespeichert. Das hat den Vorteil, dass sich die Speicherverwaltung vereinfacht, denn das Objekt verliert seine Gültigkeit, wenn das Containerobjekt aufgelöst wird.
Nachteile Der Nachteil liegt auf der Hand - durch das Erstellen einer Kopie geht Zeit und Speicherplatz verloren. Es gibt aber auch Wege, Zeiger in Containern zu speichern
at()
Damit auch Pufferüberläufe abgefangen werden können, brauchen wir eine neue Elementen-Funktion. Das at( ).
Die Methode at(), die den Index als Parameter erwartet und eine Grenzprüfung ausführt, gibt den Buchstaben an der jeweiligen Stelle zurück.
Im Fehlerfall löst sie eine out_of_range-Exception aus.
#include <iostream>
#include <string>
using namespace std;
int main() {
string zeichenkette = "Ich bin ganz lang!";
cout << zeichenkette[4] << endl;
cout << zeichenkette.at[4] << endl;
cout << zeichenkette[20] << endl; // ausgabe von Datenmüll (out_of_range)
cout << zeichenkette.at[20] << endl; // Laufzeitfehler (what(): basic_string::at)
}
Grösse erfahren!
Die Anzahl Elemente zur Laufzeit kannst du bei den vector-Arrays mit der Funktion size() ermitteln.
cout << vecray.size() << endl; ## Grösse eines Arrays
cout << vecray.length() << endl; ## Länge eines Stings
String
String-Funktionen nutzen zu können, müssen wir eine neue Bibliothek einbinden:
< string > für C++
string einString01;
string einString02 = ’’ Voll einfach ’’;
getline(cin, einString01);
Probleme
#include <string>
int main() {
string zeichenkette;
cin >> zeichenkette;
cout << zeichenkette;
}
Diese Art der Eingabe erlaubt es lediglich, bis zum nächsten Whitespace einzulesen. Es kommt jedoch häufig vor, dass man eine Zeichenkette bis zum Zeilenende oder einem bestimmten Endzeichen einlesen möchte.
Die Funktion getline()
Did you get the line? Yeah i’ve got the line with getline()!
In diesem Fall ist die Funktion getline() hilfreich. Sie erwartet als ersten Parameter einen Eingabe stream und als zweiten ein string-Objekt.
int main() {
string zeichenkette;
// Liest bis zum Zeilenende
getline(cin, Zeichenkette);
cout << zeichenkette;
}
Zuweisen und Verketten
Für die Verkettung von strings wird der + Operator benutzt und das Anhängen einer Zeichenkette ist mit += möglich.
int main() {
string string1, string2 string3;
string1 = "ich bin ";
string2 = "ein JS-Dev";
string3 = string1 + string2;
cout << string3 << endl;
string3 += " - " + string1 + "schön";
cout << string3 << endl;
}
Methoden
Die string-Klasse stellt einige nützliche Methoden bereit. Etwa um den String mit etwas zu füllen, ihn zu leeren oder über verschiedene Eigenschaften Auskunft zu bekommen. Eine Methode wird mit folgender Syntax aufgerufen:
<stringname>.<mehtodenname> ("paramenter");
- size() und length()
- empty() (true or false)
- clear()
- resize()
- swap() (String austauschen)
- Und viele andere.
Das Zählen beginnt mit 0
In der Informatik beginnt das Zählen nicht mit 1, sondern mit 0. Deshalb sollte man auch bei den Zählvariablen bei 0 beginnen. Durchlauf-Bedingung anpassen. Bei der Ausgabe des Werts um eins erhöht ausgeben (i+1).
char
Wir haben gelernt, dass wir für die Verarbeitung von einzelnen Zeichen den Datentyp char verwenden. Nun lernen wir den Umgang mit Zeichenketten, auch Strings genannt. Das sind aneinandergereihte Zeichen. Also ein char-Array
String Objekt erstellen
Wie Ihnen bereits bekannt ist, werden einzelne Zeichen in einfachen Anführungszeichen geschrieben.
Dieser Zeichenliteral ist dann vom Typ char.
char titel[]={'H', 'a', 'l', 'l', 'o', ' ', 'W', 'e', 'l', 't', '!', '\0'};
Die doppelten Anführungszeichen erzeugen hingegen eine Instanz eines char-Arrays.
char titel[]="Hallo Welt!";
Nullterminiert
Ein String besteht in C/C++ aus einem char-Feld. Dieses Feld ist meist grösser als der der String selbst. Ein Beispiel:
char text[100] = "Hallo";
Hier speichern wir in einem Feld der Grösse 100 lediglich 5 Zeichen.
ASCII-Zeichen 0 abgeschlossen
Wo ist das Ende der Zeichenkette?
Strings werden mit dem ASCII-Zeichen 0
abgeschlossen: '\0'.
Im Hauptspeicher steht nicht nur “Hallo”,
sondern "Hallo\0".
Bei der Initialisierung ohne die geschweiften Klammern und bei den String-Funktionen wird das Ende-Zeichen automatisch gesetzt.
Das Ende-Zeichen dient also nur zur Markierung, deshalb ist es bei der Ausgabe auch nicht zu sehen. Wir sprechen hierbei von sogenannten nullterminierten Strings. Bei der Deklaration von String-Feldern sollte also auch immer an das Ende-Zeichen gedacht werden!
Beispiel: Zeichenkette mit String/Klasse
Ein Objekt der Klasse String wird hier erzeugen. (Nach OOP gesprochen)
string satz; //Die Klasse heisst STRING!
satz = “Das ist “;
cout « satz « endl;
Typumwandlung nach C oder C++ String-Streams
Möchte man Zahlen verarbeiten, welche in einem String vorkommen, gibt es eine Reihe von Umwandlungsfunktionen dafür. Hierfür wird die Bibliothek stdlib.h oder cstdlib benötigt. Das sind die Funktions-Prototypen:
- String zu int: atoi
- String zu long int: atol
- String zu double: atof
Bsp.
int main() {
char charNumber1[] = "100";
char charNumber2[] = "23";
int number1 = atoi(charNumber1);
int number2 = atoi(charNumber2);
int sum = number1 + number2;
cout << number1 << " + " << number2 << " = " << sum;
cout << endl;
system("PAUSE");
return 0;
}
Funktionen
Teilprobleme legen wir als “Funktion” getrennt vom Hauptprogramm ab. Eine Funktion erledigt immer eine bestimmte Aufgabe.
Eine Funktion hat folgende Eigenschaften:
- Bezeichner, ein Name unter der sieansprechbar ist, z.B. addiere()
- Bezeichner der Parameter, z.B. summand1, summand2
- Datentyp der Parameter, z.B. int/double/etc.
Gibt eine Funktion nichts zurück, verwenden wir das Schlüsselwort void, welches einen nicht-existenten Wert darstellt.
Beispiel

Rekursion
Jede Funktion kann sowohl andere Funktionen als auch sich selbst aufrufen. Ein solcher Selbstaufruf wird auch rekursiver Aufruf genannt. Das dahinter stehende Konzept bezeichnet man entsprechend als Rekursion. Eine Ausnahme von dieser Regel bildet wieder einmal die Funktion main(). Sie darf ausschliesslich vom Betriebssystem aufgerufen werden, also weder von einer anderen Funktion, noch aus sich selbst heraus.
call-by-value
Bei call-by-value (Wertübergabe) wird der Wert des Arguments in einen Speicherbereich kopiert, auf den die Funktion mittels Parametername zugreifen kann.
call-by-reference
Sollen die von einer Funktion vorgenommen Änderungen auch für das Hauptprogramm sichtbar sein, müssen sogenannte Zeiger verwendet werden.
Zeiger
Zum Beispiel arbeiten wir mit grossen Datenmengen, welche von Funktionen bearbeiten werden sollen. Würden wir diese Datenmengen als Paket zu den Funktionen transportieren, geht dies sehr stark zu Lasten der Performance und des Speicherplatzes. Um dem vorzubeugen, verwenden wir Zeiger.
Die Datenmengen liegen im Speicher und haben eine Adresse. Ein Zeiger “zeigt” auf die Menge, indem er lediglich die Adresse der Menge speichert. Wenn wir dann einer Funktion unsere Datenmenge überliefern möchten, teilen wir ihr lediglich mit dem Zeiger die Adresse mit.
Die Datenmenge wird dabei nicht transportiert, stattdessen greift die Funktion über die Adresse auf die Daten zu. Datenmengen werden durch Variablen repräsentiert. Ein Zeiger speichert also nur die Adresse einer anderen Variablen und leitet somit die Anfrage auf einen Wert weiter.
Ein Zeiger repräsentiert eine Adresse und nicht wie eine Variable einen Wert. Will man auf den Wert der Adresse zugreifen, auf die ein Zeiger zeigt, muss der Stern * vor den Namen gesetzt werden.
Beispiel
int *Variable = Bei der Deklarierung einer Variable kann die Variable als Zeiger definiert werden. &Variable = Gibt die Adresse bekannt ! Die Variable muss den gleichen Datentyp haben wie den *Zeiger !
int zahl = 7;
int *zeiger;
zeiger = &zahl; //Zeiger verbinden Adresse
Ausgabe:
cout<<"Zeiger-Wert: " *zeiger; //Dereferenzierung = Wert ausgeben
cout<<"Zeiger-Wert: " zeiger; //Adresse der Variable anzeigen
Ausgabe über Adresse (Wert) = 7.
Referenzen
Was ist das?
Referenzen sind interne Zeiger auf Variablen. Sie werden also genau so verwendet wie gewöhnliche Variablen, verweisen jedoch auf das Objekt, mit dem sie initialisiert wurden. Die Zeigerverwendung wird vor dem Programmierer verborgen.
int a = 1; // eine Variable
int &r = a; // Referenz auf die Variable a
Wofür Referenzen?
Vielleicht haben Sie sich bereits gefragt, wofür Referenzen nun eigentlich gut sind, schliesslich könnte man ja auch einfach die Originalvariable benutzen. Referenzen bieten in einigen Anwendungsfällen eine Beschleunigung und bessere Lesbarkeit der Quelltexte.
Wichtig: Sie müssen initialisiert werden.
Array
Der englische und gängigere Begriff für Feld ist Array. Für ein Array müssen wir lediglich eine Deklaration machen.
Um viele Variablen auf einmal zu erstellen können Sie dies mit einem Array realisieren.
Beispiel
double messwerte[1440];
Einfacher geht es mit einem Feld von Variablen. Hierfür benötigen wir lediglich eine Deklaration.
Hier haben wir 1440 Variablen auf einen Schlag angelegt.
Zugriff
Der Zugriff auf diese Variablen erfolgt mittels einer Nummer, auch Index genannt. Aufdie Elemente des Arrays wird dann über diese Indexoperator zugegriffen. Dieser Index liegt im Bereich 0 und Feldgrösse minus 1, da wir bekanntlich bei Null anfangen zu zählen.
Initalisierung
Bei der Definition sind der Typ der Elemente und die Grösse des Arrays anzugeben stehen Ihnen folgende Möglichkeiten stehen zum Anlegen eines Array zur Verfügung:
Möchte man die Werte eines Feldes Initialisieren, schreibt man die Werte einfach in geschweifte Klammern.
Ist die Anzahl der Werte bei der Initialisierung kleiner als die Feldgrösse, werden die restlichen Werte auf Null 0 gesetzt.
int punkte[5] = { 1, 3, 5 };
Alles mit Null: Dadurch lässt sich ein Feld auch einfach komplett mit Null-Werten initialisieren:
int punkte[5] = { 0 };
Lässt man bei der Initialisierung die Angabe für die Feldgrösse weg, wird automatisch die Grösse durch die Anzahl der Initialisierungswerte bestimmt.
Dieses Array wird die Grösse 3 haben:
int punkte[] = { 1, 2, 3 };
//Anlegen ohne Initialisierung
int feld [10];
//Mit Initialisierung (automatisch 10 Elemente)
int feld[] = {1,2,3,4,5,6,7,8,9,10};
//10 Elemente, mit Initialisierung
int feld[10] = {1,2,3,4,5,6,7,8,9,10};
Schlaufen und Array
Mit den Schleifen können wir die einzelnen Elemente des Arrays sehr einfach ansprechen.
int punkte[5], i;
for(i=0; i<5; i++)
{
punkte[i] = i+1;
cout << punkte[i] << endl;
}
Zweidimensionale Felder
Bisher haben wir eindimensionale Felder kennengelernt, die einer einfachen Liste entsprachen.
Für viele Zwecke benötigt man aber mehrdimensionale Felder. Im Folgendem wollen wir ein Schachbrett simulieren.
Schachbrett
Ein Schachbrett hat 8 x 8 Felder, die wir mit einem zweidimensionalen Array darstellen können.
int brett[Y][X];
Insgesamt haben wir hier 8 * 8 Elemente, also 64.
Koordinatensystem
Man kann sich das Brett wie ein Koordinatensystem vorstellen, wobei man mit dem ersten Index die Y-Achse und mit dem zweiten Index die X-Achse anspricht:
brett[Y][X]
Allgemein wird bei Null angefangen zu zählen und von rechts her hochgezählt. Bei unserem Beispiel mit zwei Dimensionen und 12 Initialisierungs-Werten sind dabei folgende Indexierungen betroffen:
Zeile 1: [0][0], [0][1], [0][2], [0][3], [0][4], [0][5], [0][6], [0][7]
Zeile 2: [1][0], [1][1], [1][2], [1][3]

Zeigerarithmetik
Ein Array besteht im Prinzip nur aus Zeigern, welche auf die zum Array gehörenden Variablen zeigen. Der Zugriff auf die Variablen erfolgt also mittels Zeiger. Dazu benötigen Sie einen Positionszeiger.
Alternative Adressoperator &
Alternativ erhalten wir die erste Adresse eines Feldes auch mit dem Adressoperator & und der Indexierung auf das erste Element, z.B.
&punkte[0].
Mit diesem Operator können Sie die Adresse des Feldes herausfinden.
Hinweis zur Speicherverwaltung
In den bisherigen Beispielen haben wir Felder deklariert, bei denen die Grösse zur Compilezeit bereits feststand. Da es nicht sehr effizient ist, immer den grösstmöglichen Speicher zu reservieren, gibt es die dynamische Speicherverwaltung.
int array1[100];
// kein Standard:
int size = 200;
int array2[size];
Strukturen
Wenn du unterschiedliche Typen verwenden willst oder musst, kannst du diese in einer Struktur zusammenfassen.
struct schuhe
{
string marke;
unsigned short Groesse;
string verschluss;
string farbe;
}
Mit dem Schlüsselwort struct und der sich öffnenden geschweiften Klammer leitest du die Zusammenfassung der unterschiedlichen Typen und des Namens schuhe ein. Jetzt folgen die einzelnen Strukturmitglieder (Members), in denen die eigentlichen Daten gespeichert werden. Hier kannst du alle bekannten Typen verwenden. Am Ende wird diese Zusammenfassung der Struktur mit einer sich schliessenden geschweiften Klammer und einem Semikolon beendet.
Eine neue Variable erstellen
Nachdem du deine Typen in der Struktur zusammengefasst hast, kannst du im Programm folgendermassen einen neuen Schuh erstellen:
schuhe einSchuh, nocheinSchuh;
Zugriff auf die Daten
Der Zugriff auf die einzelnen Strukturmitglieder erfolgt dann über den Bezeichner der Struktur, gefolgt vom Punkteoperator und dann dem Strukturmitglied:
structbezeichner.structmitglied
Prototypen
Wir müssen dem Compiler erst eine Funktion bekanntmachen, bevor wir sie aufrufen können. Dies erreichen wir, indem wir die Funktionen über unser Hauptprogramm platziert haben.
Wir wollen dies mittels den Funktions-Prototypen ändern. Diese platzieren wir über das Hauptprogramm, wobei der Funktionskörper dann an einer beliebigen Stelle im Skript sein darf.
#include<31231>
// Anmeldung von Funktions-Prototypen
double multipliziere(double zahl1, double zahl2);
// Ab hier das Hauptprogramm
int main() {}
// Eigentliche Funktion
double multipliziere(double zahl1, double zahl2)
{
return (zahl1 * zahl2);
}
Befehle
main
“Hier beginnt das Hauptprogramm”. Eine main Funktion wird immer benötigt damit der Compiler weiss wo er beginnen muss, das Programm zu übersetzten
void
void in der main()-Funktion steht für einen “leeren” Datentyp (🕳️)
;
Es wird hauptsächlich dazu verwendet, das Ende einer Anweisunganzuzeigen. Er Fährt dann nach der Abarbeitung der Anweisung mit der nächsten Zeile fort.
{}
Zwischen den geschweiften Klammern steh Anweisungsblock.
return 0
Die main-Funktion bekommt den Rückgabewert 0. Das bedeutet das Programm wurde ordnungsgemäss beendet
stdio
stdio steht für Standard-Input/Output.
bool
Eine boolische Variable hat zwei Werte “true oder false”.Intern wird bool als Zahl abgespeichert abgespeichert
short
Kann Positivzahlen bis 32767 abspeichern. Short ist dafür Effizienter als int und benötig weniger Computerressourcen. Falls man nur positive Zahlen will, sollte man “unsigned short” benutzen. Damit verdoppelt sich die mögliche Zahlenmenge.
double
Fliesskommazahlen. Double kann Dezimalzahlen oder als Zahlen mit Zehnerexponent eingegeben werden. double ist etwas genauer wie float (64-Bit-Zahl -> doppelt so grosser Zahlenraum)
float
Fliesskommazahlen. Double kann Dezimalzahlen oder als Zahlen mit Zehnerexponent eingegeben werden. Ist etwas ungenauer wie double (32-Bit-Zahl)
string
ABC
char
symbolisch (Einzelne Buchstaben, Zahlen oder Sonderzeichen). Eingabe mit einfachen Hochkommas (A 8 %). Abgespeichert wird eine Zahl gemäss dem Zeichencode.
string und char
Eine Zeichenfolge (String) kann mit einem Feld von char abgespeichert werden. char
int
Ganzzahlen
Noch mehr “long double”
printf() Ist eine Funktion aus der Headerdatei stdio.h . Beliebige String konstante formatiert auf dem Bildschirm aus. Steht immer zwischen zwei Hochkommata ( “HALLO“ ).
getchar()
Getchar kann ein Zeichen speichern das vom Nutzer eingegeben wurde, und dies dan später ausgeben.
int main() =
Hier beginnt das Hauptprogramm. Eine main-Funktion wird immer benötigt, damit der Compiler weiss, wo er beginnen muss, das Programm zu übersetzen. (Hauptfunktion)
return 0
In diesem Programm bekommt die main-Funktion den Rückgabewert 0. Das bedeutet: Das Programm wurde ordnungsgemäss beendet.
{}
Zwischen den geschweiften Klammern steht unser Anweisungsblock. Geschweifte Klammern fassen Anweisungen zu einem Block zusammen.
static
Durch static wird der letzte Wert in der in einer Variable “lokal in einer Funktion” gespeichert. Static benötigt immer einen Anfangswert