C++ Grundlagen - © M. Meili

Lernhilfe für C++

1. Kommentare und Dokumentation

Kommentare im Code
// Einzeiliger Kommentar int x = 5; // Variable mit Wert 5 /* Mehrzeiliger Kommentar Erklärt mehrere Zeilen oder einen Abschnitt */ int y = 10;
Kommentare helfen dabei, Code zu erklären und verständlicher zu machen.

2. Namensräume (namespace)

Was ist ein Namensraum?
#include <iostream> // Ohne using namespace std: int main() { std::cout << "Hallo Welt!" << std::endl; return 0; }
Namensräume verhindern Namenskonflikte. Mit using namespace std; kann man cout und endl direkt verwenden.

3. Header-Dateien & Modularisierung

Code-Aufteilung mit Headerdateien
// Datei: funktionen.h int quadriere(int x); // Datei: funktionen.cpp int quadriere(int x) { return x * x; } // Datei: main.cpp #include "funktionen.h" #include <iostream> using namespace std; int main() { cout << quadriere(7) << endl; return 0; }
Headerdateien (.h) enthalten Deklarationen, Implementierungen stehen in .cpp-Dateien.

4. Fehlerbehandlung (Exceptions)

try-catch Beispiel
#include <iostream> using namespace std; int main() { try { int teiler = 0; if (teiler == 0) throw "Division durch Null!"; cout << (10 / teiler) << endl; } catch (const char* msg) { cout << "Fehler: " << msg << endl; } return 0; }
Mit try und catch kann man Fehler gezielt abfangen und behandeln.

5. Operatoren

Vergleichs- und logische Operatoren
int a = 5, b = 10; if (a == b) // Gleichheit if (a != b) // Ungleichheit if (a > b) // Grösser if (a < b) // Kleiner // Logische Operatoren if (a > 0 && b > 0) // UND if (a > 0 || b > 0) // ODER if (!(a == b)) // NICHT
Vergleichs- und logische Operatoren helfen beim Prüfen von Bedingungen.
Zuweisungsoperatoren
int x = 5; x += 2; // x = x + 2 x -= 4; // x = x - 4 x *= 3; // x = x * 3 x /= 2; // x = x / 2
Zuweisungsoperatoren sparen Schreibarbeit und machen Code übersichtlicher.

6. Variablen und Datentypen

Grundlegende Datentypen
#include <iostream> using namespace std; int main() { // Ganze Zahlen int alter = 18; // Dezimalzahlen double preis = 19.95; // Zeichen char note = 'A'; // Wahrheitswerte bool istStudent = true; return 0; }
Verschiedene Datentypen für unterschiedliche Arten von Werten.

7. Ein- und Ausgabe

Einfache Ausgabe mit cout
#include <iostream> using namespace std; int main() { cout << "Hallo du da!" << endl; cout << "Mein erstes C++ Programm" << endl; return 0; }
Ausgabe:
Hallo du da!
Mein erstes C++ Programm
Eingabe mit cin
#include <iostream> using namespace std; string name; int alter; cout << "Wie heisst du? "; cin >> name; cout << "Wie alt bist du? "; cin >> alter; cout << "Hallo " << name << ", du bist " << alter << " Jahre alt!" << endl;
Ein Benutzer kann Daten eingeben, die dann verarbeitet werden.

8. Bedingungen (if/else)

Einfache if-Abfrage
#include <iostream> using namespace std; int punkte = 85; if (punkte >= 90) { cout << "Sehr gut!" << endl; } else if (punkte >= 70) { cout << "Gut!" << endl; } else { cout << "Mehr üben!" << endl; }
Ausgabe: Gut!
Das Programm prüft verschiedene Bedingungen und gibt entsprechende Nachrichten aus.

9. Schleifen

For-Schleife
#include <iostream> using namespace std; // Zahlen von 1 bis 5 ausgeben for (int i = 1; i <= 5; i++) { cout << "Zahl: " << i << endl; }
Ausgabe:
Zahl: 1
Zahl: 2
Zahl: 3
Zahl: 4
Zahl: 5
While-Schleife
int countdown = 3; while (countdown > 0) { cout << countdown << "... "; countdown--; } cout << "Start!" << endl;
Ausgabe: 3... 2... 1... Start!
For-Each Schleife (Range-based)
int zahlen[] = {5, 10, 15, 20, 25}; // For-Each: durchläuft automatisch alle Elemente cout << "Alle Zahlen:" << endl; for (int zahl : zahlen) { cout << zahl << " "; } cout << endl;
Ausgabe: Alle Zahlen:
5 10 15 20 25
For-Each ist einfacher zu schreiben und weniger fehleranfällig bei Arrays.
Do-While Schleife
int zahl; // Do-While läuft mindestens einmal do { cout << "Gib eine Zahl zwischen 1 und 5 ein: "; cin >> zahl; if (zahl < 1 || zahl > 5) { cout << "Falsche Eingabe!" << endl; } } while (zahl < 1 || zahl > 5); cout << "Richtig! Zahl: " << zahl << endl;
Do-While prüft die Bedingung am Ende - Code wird garantiert mindestens einmal ausgeführt.

10. Funktionen (erweitert)

Funktions-Prototypen
#include <iostream> using namespace std; // Funktions-Prototypen (Deklarationen) void begruessung(); int addieren(int a, int b); int main() { begruessung(); int ergebnis = addieren(5, 3); cout << "Addieren: " << ergebnis << endl; return 0; } // Funktions-Definitionen void begruessung() { cout << "Willkommen!" << endl; } int addieren(int a, int b) { return a + b; }
Prototypen ermöglichen es, Funktionen vor ihrer Definition zu verwenden.
Funktionen mit und ohne Rückgabe
#include <iostream> using namespace std; // Funktion OHNE Rückgabe (void) void ausgabe(string text) { cout << "Ausgabe: " << text << endl; } // Funktion MIT Rückgabe double kreisflaeche(double radius) { const double PI = 3.14159; return PI * radius * radius; } int main() { ausgabe("Hallo du da"); double flaeche = kreisflaeche(5.0); cout << "Kreisfläche: " << flaeche << endl; return 0; }
Ausgabe:
Ausgabe: Hallo du da
Kreisfläche: 78.5398
void-Funktionen geben nichts zurück, andere Funktionen müssen immer einen Wert zurückgeben.
Parameter als Referenz (&)
void aendernReferenz(int& zahl) { zahl = 999; } int main() { int wert2 = 42; aendernReferenz(wert2); cout << wert2 << endl; // 999 }
Referenzen (&) ändern die ursprüngliche Variable, normale Parameter nur eine Kopie.
Parameter als Zeiger (*)
void verdoppeln(int* zahl) { if (zahl != nullptr) { *zahl = *zahl * 2; } } int main() { int wert = 21; verdoppeln(&wert); cout << wert << endl; // 42 }
Zeiger (*) arbeiten mit Speicheradressen. & gibt die Adresse, * dereferenziert den Zeiger.

11. Arrays und Vektoren

Normales Array
int zahlen[5] = {10, 20, 30, 40, 50}; cout << "Erstes Element: " << zahlen[0] << endl; for (int i = 0; i < 5; i++) { cout << "Index " << i << ": " << zahlen[i] << endl; }
Arrays haben eine feste Grösse, die zur Compile-Zeit festgelegt wird.
Vector (dynamisches Array)
#include <vector> using namespace std; vector<int> zahlen = {1, 2, 3}; zahlen.push_back(4); zahlen.push_back(5); cout << "Grösse des Vectors: " << zahlen.size() << endl;
Vektoren sind flexibler als Arrays - Grösse kann zur Laufzeit geändert werden.

12. Strings (Texte)

String-Grundlagen
#include <string> using namespace std; string vorname = "Max"; string nachname = "Mustermann"; string vollname = vorname + " " + nachname; cout << vollname << endl; cout << vollname.length() << endl;
Ausgabe:
Max Mustermann
14
String-Eingabe mit Leerzeichen
#include <string> using namespace std; string satz; cout << "Gib einen ganzen Satz ein: "; getline(cin, satz); cout << "Du hast gesagt: " << satz << endl;
getline() liest eine komplette Zeile inklusive Leerzeichen.

13. Mathematische Operationen

Grundrechenarten
int a = 10, b = 3; cout << a + b << endl; cout << a - b << endl; cout << a * b << endl; cout << a / b << endl; cout << a % b << endl;
Ausgabe:
13
7
30
3
1
Inkrement und Dekrement
int zahl = 5; zahl++; cout << zahl << endl; // 6 zahl--; cout << zahl << endl; // 5 zahl += 3; cout << zahl << endl; // 8
Ausgabe:
6
5
8

14. Switch-Case Anweisungen

Menü-Auswahl mit Switch
int wahl; cout << "Wähle eine Option: "; cin >> wahl; switch (wahl) { case 1: cout << "Spiel wird neu gestartet..." << endl; break; case 2: cout << "Spiel wird geladen..." << endl; break; case 3: cout << "Auf Wiedersehen!" << endl; break; default: cout << "Ungültige Eingabe!" << endl; }
Switch-Case ist übersichtlicher als viele if-else Anweisungen bei mehreren Optionen.

15. Konstanten

Konstanten definieren
const double PI = 3.14159; const int MAX_PUNKTE = 100; const string PROGRAMM_NAME = "C++ Lernprogramm";
Konstanten machen Code sicherer und lesbarer. Verwende GROSSBUCHSTABEN für Konstanten-Namen.

16. Objektorientierung – Konstruktor, Destruktor & Vererbung (Ausblick)

Konstruktor und Destruktor
class Person { public: Person() { // Konstruktor std::cout << "Objekt erstellt!" << std::endl; } ~Person() { // Destruktor std::cout << "Objekt zerstört!" << std::endl; } };
Konstruktor: wird beim Erstellen eines Objekts ausgeführt.
Destruktor: wird beim Löschen eines Objekts ausgeführt.
Vererbung (als Ausblick)
class Tier { public: void bewegen() { std::cout << "Das Tier bewegt sich." << std::endl; } }; class Hund : public Tier { public: void bellen() { std::cout << "Der Hund bellt." << std::endl; } };
Vererbung erlaubt es, Eigenschaften und Methoden von einer Klasse an eine andere weiterzugeben.

17. Die C++ Standardbibliothek

Nützliche Standardbibliotheken
#include <cmath> // Mathematische Funktionen #include <algorithm> // Sortieren, Suchen, etc. #include <map> // Schlüssel-Wert Zuordnung #include <set> // Mengen ohne Duplikate #include <fstream> // Datei-Ein/Ausgabe
Die Standardbibliothek bietet viele vorgefertigte Funktionen und Datenstrukturen.

18. Dateiein- und -ausgabe

Textdatei lesen und schreiben
#include <fstream> #include <iostream> using namespace std; // Schreiben ofstream datei("test.txt"); datei << "Hallo Datei!" << endl; datei.close(); // Lesen ifstream lesen("test.txt"); string zeile; while (getline(lesen, zeile)) { cout << zeile << endl; } lesen.close();
Mit ofstream und ifstream kann man Dateien schreiben und lesen.

19. Dynamische Speicherverwaltung

Speicher reservieren und wieder freigeben
int* p = new int(42); cout << *p << endl; delete p;
Dynamischer Speicher muss mit delete wieder freigegeben werden.
Nutze besser std::vector und std::string für dynamische Daten.
Smart Pointer (moderne Alternative)
#include <memory> auto sp = std::make_unique<int>(100); cout << *sp << endl;
Smart Pointer wie std::unique_ptr übernehmen die Speicherverwaltung automatisch.

20. Einfache Klassen (Einführung)

Einfache Student-Klasse
#include <iostream> #include <string> using namespace std; class Student { public: string name; int alter; double note; void vorstellen() { cout << "Hallo, ich bin " << name << ", " << alter << " Jahre alt und habe eine Note " << note << endl; } }; int main() { Student student1; student1.name = "Anna"; student1.alter = 19; student1.note = 4.5; student1.vorstellen(); return 0; }
Ausgabe: Hallo, ich bin Anna, 19 Jahre alt und habe eine Note 4.5
Klassen gruppieren zusammengehörige Daten und Funktionen. Ein Objekt ist eine "Instanz" einer Klasse.
Rechteck-Klasse mit Berechnung
class Rechteck { public: double laenge; double breite; double flaeche() { return laenge * breite; } double umfang() { return 2 * (laenge + breite); } }; int main() { Rechteck meinRechteck; meinRechteck.laenge = 5.0; meinRechteck.breite = 3.0; cout << "Fläche: " << meinRechteck.flaeche() << endl; cout << "Umfang: " << meinRechteck.umfang() << endl; return 0; }
Ausgabe:
Fläche: 15
Umfang: 16
Klassen können eigene Funktionen (Methoden) haben, die mit den Klassendaten arbeiten.