Erst kompilieren, dann ausführen
Jetzt, da du einen Compiler installiert hast, ist es ein zweistufiger Zyklus, ein C++-Programm zum Laufen zu bringen. Anders als bei einer Skriptsprache, bei der ein Interpreter deine Datei Zeile für Zeile liest, kompiliert C++ deinen Quellcode zuerst in eine native ausführbare Datei - ein eigenständiges Binary aus Maschinencode - und dann führst du dieses Binary direkt aus. Zur Laufzeit sitzt kein Interpreter zwischen deinem Programm und der CPU.
Diese Trennung ist der Grund, warum C++ schnell ist - und auch der Grund, warum ein Syntaxfehler dich zur Kompilierzeit stoppt statt mitten im Lauf. Der Compiler prüft die ganze Datei, bevor er irgendetwas erzeugt.
Jedes in sich geschlossene Beispiel kannst du direkt hier auf der Seite ausführen - der Editor unten kompiliert und startet es für dich. Aber es lohnt sich zu wissen, was auf deinem eigenen Rechner passiert, denn dort leben die echten Projekte.
Der Kompilieren-und-Ausführen-Zyklus auf deinem Rechner
Angenommen, du hast das hier als main.cpp gespeichert:
#include <iostream>
using namespace std;
int main() {
cout << "Hello from the terminal" << endl;
return 0;
}
Öffne ein Terminal in dem Ordner mit der Datei und rufe den Compiler auf. Der gängigste Compiler ist g++ (Teil von GCC); clang++ funktioniert für alles hier genauso:
g++ main.cpp -o main
Wenn der Code sauber kompiliert, gibt g++ nichts aus und legt neben deinem Quellcode eine neue Datei an: eine ausführbare Datei namens main (oder main.exe unter Windows). Dieses Binary ist Maschinencode - kein lesbarer Text und an dein Betriebssystem und deine CPU gebunden. Jetzt führe es aus:
./main
Hello from the terminal
Unter Windows würdest du es als main.exe (oder einfach main) aus demselben Terminal starten. Das ./ unter macOS und Linux sagt der Shell „das Programm ist genau hier in diesem Ordner, nicht irgendwo im PATH" - ein Schritt, den Anfänger vergessen und sich dann wundern, warum main command not found meldet.
Was -o macht (und a.out)
Die Option -o benennt die Ausgabe. Lässt du sie weg, kompiliert g++ trotzdem, schreibt die ausführbare Datei aber unter einem Standardnamen: a.out unter macOS/Linux, a.exe unter Windows.
g++ main.cpp # produces a.out, not main
./a.out
Das bringt Leute ständig durcheinander: Sie kompilieren, sehen keine Fehler, führen ./main aus und bekommen No such file or directory - weil das Binary in Wirklichkeit a.out heißt. Gib immer -o an, damit du genau weißt, was du ausführst.
Du kompilierst einmal pro Änderung am Quellcode. Danach ist die ausführbare Datei eigenständig - du kannst ./main hundertmal ausführen, ohne neu zu kompilieren. g++ startest du erst wieder, nachdem du die .cpp-Datei bearbeitet hast.
Einen C++-Standard wählen
C++ hat Versionen - C++11, C++14, C++17, C++20, C++23 - jede fügt der Sprache Features hinzu. Der Haken: Dein Compiler wählt einen Standard, der älter sein kann als erwartet, sodass moderner Code ohne ersichtlichen Grund nicht kompiliert. Setze den Standard explizit mit -std:
g++ -std=c++17 main.cpp -o main
g++ -std=c++20 main.cpp -o main
Hier ist Code, der ein C++17-Feature nutzt (structured bindings). Im Editor kompiliert er problemlos, aber auf deinem Rechner braucht er -std=c++17 oder neuer:
Wenn du jemals einen Fehler wie 'structured bindings' only available with '-std=c++17' siehst, liegt die Lösung nicht in deinem Code - sondern darin, die richtige -std-Option hinzuzufügen. Geh in diesem Kurs durchgehend von C++17 oder neuer aus.
Warnungen einschalten
Ein C++-Programm kann sauber kompilieren und trotzdem falsch sein. Der Compiler weist dich, wenn du ihn lässt, auf verdächtigen Code hin, bevor er dich zur Laufzeit beißt. Füge -Wall -Wextra hinzu:
g++ -std=c++17 -Wall -Wextra main.cpp -o main
Schau dir dieses Programm an. Ohne -Wall kompiliert es, hat aber einen echten Bug - es liest eine Variable, der nie ein Wert zugewiesen wurde, was undefiniertes Verhalten ist:
#include <iostream>
using namespace std;
int main() {
int count; // never initialized
cout << count << endl; // reads garbage - undefined behavior
return 0;
}
Mit eingeschalteten Warnungen meldet der Compiler es:
warning: 'count' is used uninitialized [-Wuninitialized]
Gewöhne dir ab dem ersten Tag an, mit -Wall -Wextra zu kompilieren. Warnungen sind der Compiler, der dir ein kostenloses Code-Review gibt; sie zu ignorieren ist der Weg, auf dem subtile Bugs überleben. Die Lösung hier ist einfach int count = 0;.
Compiler-Fehler lesen
Wenn g++ deinen Code ablehnt, nennt er die Datei, die Zeile und was schiefgelaufen ist. Diese Meldungen lesen zu lernen, ist die halbe Miete, um wieder weiterzukommen. Hier ist der Klassiker - ein fehlendes Semikolon:
#include <iostream>
using namespace std;
int main() {
cout << "Oops" // no semicolon
return 0;
}
main.cpp:5:5: error: expected ';' before 'return'
5 | return 0;
| ^~~~~~
Ein paar Dinge sind zu beachten. Der Fehler meldet Zeile 5, aber der Fehler steckt in Zeile 4 - der Compiler merkt erst, dass ein Semikolon fehlt, wenn er das nächste Token erreicht. Wenn ein Fehler also auf eine Zeile zeigt, die in Ordnung aussieht, prüfe die Zeile davor. main.cpp:5:5 ist Datei, Zeile, dann Spalte. Behebe genau das eine, was er benennt, und kompiliere neu - widerstehe dem Raten.
Compiler-Fehler bedeuten, dass noch nichts gelaufen ist. Sie unterscheiden sich von Laufzeitfehlern, bei denen dein Programm gestartet ist und dann abgestürzt ist. Fehler zur Kompilierzeit abzufangen, bevor das Programm überhaupt läuft, ist eine der größten Stärken von C++.
Ein Funktionstest-Programm
Führe das im Editor aus, oder speichere es als main.cpp und mach auf deinem eigenen Rechner g++ -std=c++17 -Wall main.cpp -o main und dann ./main. Wenn alle drei Zeilen erscheinen, funktioniert deine Toolchain von Anfang bis Ende:
Drei Dinge tauchen hier auf, die du bald richtig kennenlernen wirst: eine int-Variable, ein vector (das größenveränderliche Array von C++) und cout für die Ausgabe. Fürs Erste reicht es, dass das Programm kompiliert und alle drei Zeilen der Reihe nach ausgibt.
Weiter: C++-Syntax
Du hast ein paar Programme kompiliert und ausgeführt, aber wir sind an der Zeichensetzung vorbeigezogen - den #include-Zeilen, den geschweiften Klammern, den Semikolons, int main() und warum jede Zeile so aussieht, wie sie aussieht. Die nächste Seite zerlegt die C++-Syntax Stück für Stück, damit sich die Struktur nicht mehr wie Boilerplate anfühlt, sondern Sinn ergibt.
Häufig gestellte Fragen
Wie kompiliere und führe ich ein C++-Programm aus?
Speichere deinen Code als main.cpp, öffne in diesem Ordner ein Terminal und führe g++ main.cpp -o main aus, um eine ausführbare Datei zu erzeugen. Starte sie dann mit ./main unter macOS/Linux oder main.exe unter Windows. Du kompilierst einmal; das entstandene Binary kannst du beliebig oft ausführen.
Was bewirkt die Option -o in g++?
-o benennt die Ausgabedatei. g++ main.cpp -o hello erzeugt eine ausführbare Datei namens hello. Lässt du -o weg, verwendet g++ standardmäßig a.out (oder a.exe unter Windows) - deshalb führen Anfänger oft eine Datei aus, von der sie gar nicht wussten, dass sie sie erstellt haben.
Wie kompiliere ich C++ mit einem bestimmten Standard wie C++17 oder C++20?
Gib die Option -std an: g++ -std=c++17 main.cpp -o main oder -std=c++20. Ohne sie nutzt der Compiler seinen eigenen Standard, der älter sein kann als erwartet, sodass neuere Features wie structured bindings oder <ranges> sich nicht kompilieren lassen, bis du den Standard explizit setzt.