Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
talit:cpp [2020-10-17 22:09] – [Makefile] scatalit:cpp [2020-10-21 06:04] (aktuell) – [3.1 Testprogramm] sps
Zeile 1: Zeile 1:
-C++ Grundlagen+====== - C++ Grundlagen ======
  
-## Installation+Diese Seite ist nicht als allumfassendes Tutorial gedacht. Es ist eher eine Sammlung von wichtigen Punkten und Links zu weiteren Quellen. Es wird davon ausgegangen, dass der Leser bereits solide Vorkenntnisse in anderen Programmiersprachen hat. Ist dies nicht der Fall, wird empfohlen, ein Einsteigertutorial zu finden. 
 + 
 +===== - Installation =====
  
 Es gibt verschiedene Möglichkeiten, um C++-Code zu kompilieren und auszuführen. Gerade für den Anfang ist es aber empfohlen, es auf die 'traditionelle' Art und Weise zu machen. Dazu soll der GNU Compiler installiert werden. Der Code wird dann //in der Konsole// zuerst kompiliert (und ein paar weitere Schritte) und danach separat ausgeführt. Es gibt verschiedene Möglichkeiten, um C++-Code zu kompilieren und auszuführen. Gerade für den Anfang ist es aber empfohlen, es auf die 'traditionelle' Art und Weise zu machen. Dazu soll der GNU Compiler installiert werden. Der Code wird dann //in der Konsole// zuerst kompiliert (und ein paar weitere Schritte) und danach separat ausgeführt.
  
-### Unix (Mac & Linux)+==== - Unix (Mac & Linux) ====
  
-Auf Unix-basierten Systemen (Mac und Linux) sollte der GNU Compiler bereits installiert sein. Mit `g++ -v` kannst du dies sicherstellen und sehen, welche Version installiert ist.+Auf Unix-basierten Systemen (Mac und Linux) sollte der GNU Compiler bereits installiert sein. Mit `g++ -v` kannst du dies sicherstellen und sehen, welche Version installiert ist. Weiter unten wird erklärt, wie man Programme kompilieren und ausführen kann. 
 +==== - Windows ====
  
-### Windows +   * MinGW: http://www.mingw.org, am einfachsten direkt http://www.mingw.org/wiki/Getting_Started
- +
-   * MinGW: http://www.mingw.org+
    * Video: https://youtu.be/sXW2VLrQ3Bs    * Video: https://youtu.be/sXW2VLrQ3Bs
    * (nicht explizit getestet)    * (nicht explizit getestet)
 +
 +Weiter unten wird erklärt, wie man Programme kompilieren und ausführen kann.
 +
 +==== - Programmierumgebung ====
 +
 +Je nachdem, an was für einem Projekt man arbeitet und welche Vorlieben man hat, kann es auch Sinn machen, mit einer Programmierumgebung (IDE) zu arbeiten. Bevor man dies tut, sollte man aber verstanden haben, wie der Build-Prozess von C++ funktioniert und man sollte in der Lage sein, Programme in der Konsole zu kompilieren und auszuführen.
 +
 +Hier ein paar Vorschläge für Programmierumgebungen (bei weitem nicht komplett) mit Tutorials zur Installation:
 +   * Visual Studio Code (Win & Mac)
 +     * Windows: https://code.visualstudio.com/docs/cpp/config-mingw
 +     * Mac: https://code.visualstudio.com/docs/cpp/config-clang-mac
 +   * Visual Studio (Win)
 +     * The Cherno: https://youtu.be/1OsGXuNA5cc
 +   * XCode (Mac)
 +     * The Cherno: https://youtu.be/1E_kBSka_ec
 +
 +
  
  
-## C++ Programmieren+===== - C++ Programmieren =====
  
-### Grundlegender Synax+==== - Grundlegende Syntax ====
  
-Es wird angenommen, dass du bereits über Vorwissen in einer anderen Programmiersprache verfügst, optimalerweise in einer typensicheren Sprache wie C# oder Java. Deshalb solltest du in der Lage sein, dir selbst den wichtigsten Syntax zu erarbeiten.+Es wird angenommen, dass du bereits über Vorwissen in einer anderen Programmiersprache verfügst, optimalerweise in einer typensicheren Sprache wie C# oder Java. Deshalb solltest du in der Lage sein, dir selbst die wichtigste Syntax zu erarbeiten.
  
-Hier einige Quellen:+Hier einige **allgemeine Quellen**:
  
    * Video Tutorial Reihe von The Cherno: https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb    * Video Tutorial Reihe von The Cherno: https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb
  
 +Falls du dich auf die **SOI** vorbereiten möchtest, macht es Sinn, Tutorials, die auf kompetitives Programmieren ausgelegt sind zu studieren:
 +   * Tutorial zu Basics: https://soi.ch/media/files/soi_cpp_tutorial.pdf
 +   * Übersicht Quellen: https://soi.ch/page/training/
 +   * Competitive Programmer's Handbook: https://cses.fi/book/index.php
 +   * Wiki von SOI.ch: https://soi.ch/wiki/
  
-### Besonderheiten von C+++==== - Besonderheiten von C++ ====
  
  
Zeile 39: Zeile 62:
  
  
-## Kompilieren & Ausführen von Code in C+++===== - Kompilieren & Ausführen von Code in C++ =====
  
 Ziel dieses Kapitels ist es, ein Verständnis zu entwickeln für die verschiedenen Schritte, die zwischen dem Code in C++ und der ausführbaren Datei liegen. Ziel dieses Kapitels ist es, ein Verständnis zu entwickeln für die verschiedenen Schritte, die zwischen dem Code in C++ und der ausführbaren Datei liegen.
Zeile 45: Zeile 68:
  
  
-### Testprogramm+==== - Testprogramm ====
  
 Dazu betrachten wir ein kleines (und ziemlich sinnloses) Programm, welches auf 3 Files aufgeteilt wurde. Stelle sicher, dass du genau verstehst, was das Programm macht. Auch sollte dir klar sein, warum es die Headerdatei `calc.h` braucht. Dazu betrachten wir ein kleines (und ziemlich sinnloses) Programm, welches auf 3 Files aufgeteilt wurde. Stelle sicher, dass du genau verstehst, was das Programm macht. Auch sollte dir klar sein, warum es die Headerdatei `calc.h` braucht.
Zeile 84: Zeile 107:
 </code> </code>
  
-<code cpp h.cpp>+<code cpp calc.h>
 void add(int,int); void add(int,int);
 void sub(int,int); void sub(int,int);
Zeile 92: Zeile 115:
  
  
-### Build-Prozess+==== - Build-Prozess ====
  
 **Quellen:** **Quellen:**
Zeile 132: Zeile 155:
 ``` ```
  
-#### Schritt 1: Preprocess+=== - Schritt 1: Preprocess ===
  
-Preprozessor Statements wie include oder if werden ausgeführt. Z.B. resultiert `#include <iostream>`, dass der gesamte Code aus iostream in den Code hinein kopiert wird.+Preprozessor Statements wie include oder if werden ausgeführt. Z.B. resultiert `#include <iostream>`, dass der gesamte Code aus iostream in den Code hineinkopiert wird.
  
 Die Flag `-E` bewirkt, dass nur der Preprocess-Schritt ausgeführt wird. Beachte, dass der Output nur in der Konsole ausgegeben wird und nicht in ein File geschrieben wird. Möchte man dies, muss man dies mit `-o outputfilename` explizit angeben. Die Flag `-E` bewirkt, dass nur der Preprocess-Schritt ausgeführt wird. Beachte, dass der Output nur in der Konsole ausgegeben wird und nicht in ein File geschrieben wird. Möchte man dies, muss man dies mit `-o outputfilename` explizit angeben.
Zeile 167: Zeile 190:
 </code> </code>
  
-Beachte, dass in den Zeilen 8-10 die Zeilen aus `calc.h` einfach hinein kopiert wurden.+Beachte, dass in den Zeilen 8-10 die Zeilen aus `calc.h` einfach hineinkopiert wurden.
  
-Das File `calc.ii` wird hier nicht gezeigt, da es mehrere 10'000 Zeilen lang ist! Der Grund ist, dass der gesamte Inhalt von iostream hinein kopiert wurde.+Das File `calc.ii` wird hier nicht gezeigt, da es mehrere 10'000 Zeilen lang ist! Der Grund ist, dass der gesamte Inhalt von iostream hineinkopiert wurde.
  
 Ein solches `.ii` File (je nach OS auch mit Endung `.i`) wird auch **Translation Unit** genannt und beinhaltet nichts weiteres als C++-Code - auch wenn das File eine andere Endung hat. Ein solches `.ii` File (je nach OS auch mit Endung `.i`) wird auch **Translation Unit** genannt und beinhaltet nichts weiteres als C++-Code - auch wenn das File eine andere Endung hat.
  
  
-#### Schritt 2: Kompilieren+=== - Schritt 2: Kompilieren ===
  
-Danach kommt der eigentliche Kompilierungsschritt. Der preprozessierte Code wird in **Maschinencode** kompiliert. Dieser wird in einem sogenannten **Object**-File (Endung: `.o` oder `.out`) gespeichert. Dieser Maschinencode beinhaltet direkte Instruktionen an die CPU. Der Die `-c` Flag bewirkt, dass der C++ Code nur preprozessiert und kompiliert wird:+Danach kommt der eigentliche Kompilierungsschritt. Der preprozessierte Code wird in **Maschinensprache** kompiliert. Dieser wird in einem sogenannten **Object**-File (Endung: `.o` oder `.out`) gespeichert. Diese Maschinensprache beinhaltet direkte Instruktionen an die CPU. Der Die `-c` Flag bewirkt, dass der C++ Code nur preprozessiert und kompiliert wird:
  
 ``` ```
Zeile 187: Zeile 210:
 Genau genommen verläuft diese Kompilierung in //zwei Schritten// ab: Genau genommen verläuft diese Kompilierung in //zwei Schritten// ab:
  
-##### Schritt 2A: Kompilieren C++ zu Assembly-Code+== - Schritt 2A: Kompilieren C++ zu Assembly-Code ==
  
 Kompilation mit GNU-Compiler in Assembly-Code (Endung: `.s`). Assembler ist eine sehr hardwarenahe Programmiersprache und ist unterschiedlich für verschiedene CPU-Typen.  Kompilation mit GNU-Compiler in Assembly-Code (Endung: `.s`). Assembler ist eine sehr hardwarenahe Programmiersprache und ist unterschiedlich für verschiedene CPU-Typen. 
Zeile 231: Zeile 254:
 </code> </code>
  
-##### Schritt 2B: Kompilieren Assembly-Code zu Maschinencode+== - Schritt 2B: Kompilieren Assembly-Code in Maschinensprache ==
  
-Die Assembly-Datei (`.s`) wird dann in Maschinencode umgewandelt. Dies passiert nicht mehr mit dem GNU-Compiler, sondern mit dem Assembler-Compiler:+Die Assembly-Datei (`.s`) wird dann in Maschinensprache umgewandelt. Dies passiert nicht mehr mit dem GNU-Compiler, sondern mit dem Assembler-Compiler:
 ``` ```
 as -o prog.o prog.s as -o prog.o prog.s
Zeile 240: Zeile 263:
  
  
-#### Schritt 3: Linking+=== - Schritt 3: Linking ===
  
 Damit das Programm ausgeführt werden muss, müssen die einzelnen Object-Files miteinander verknüpft (also gelinked) werde. Das Resultat ist dann eine ausführbare Datei (hier `main` genannt) Damit das Programm ausgeführt werden muss, müssen die einzelnen Object-Files miteinander verknüpft (also gelinked) werde. Das Resultat ist dann eine ausführbare Datei (hier `main` genannt)
Zeile 252: Zeile 275:
  
 Doch wozu braucht man diesen Linking-Schritt? Machen wir ein Beispiel: Doch wozu braucht man diesen Linking-Schritt? Machen wir ein Beispiel:
-   * in `prog.cpp` wird die Funktion `Add(...)` aufgerufen, welche im Headerfile `calc.h` deklariert ist. Im Preprocess-Schritt wird diese Deklaration dann in `prog` hinein kopiert. Die Definition fehlt aber! Das Programm `prog.o` kann alleine nicht ausgeführt werden, da sich die Definition der Funktion in `calc.o` befindet. Im Linking-Schritt wird dann die Deklaration von Add in `prog.o` mit deren Definition in `calc.o` verknüpft.  Man sieht also, dass man eine Datei auch schon kompilieren kann, wenn nur die Deklaration einer Funktion, aber nicht deren Definition enthalten ist.+   * in `prog.cpp` wird die Funktion `Add(...)` aufgerufen, welche im Headerfile `calc.h` deklariert ist. Im Preprocess-Schritt wird diese Deklaration dann in `prog` hineinkopiert. Die Definition fehlt aber! Das Programm `prog.o` kann alleine nicht ausgeführt werden, da sich die Definition der Funktion in `calc.o` befindet. Im Linking-Schritt wird dann die Deklaration von Add in `prog.o` mit deren Definition in `calc.o` verknüpft.  Man sieht also, dass man eine Datei auch schon kompilieren kann, wenn nur die Deklaration einer Funktion, aber nicht deren Definition enthalten ist.
    * Auch muss der Einstiegspunkt ins Programm, sprich die main-Funktion gefunden werden. Auch dies geschieht im Linking-Schritt.    * Auch muss der Einstiegspunkt ins Programm, sprich die main-Funktion gefunden werden. Auch dies geschieht im Linking-Schritt.
  
Zeile 258: Zeile 281:
  
  
-#### Schritt 4: Ausführen+=== - Schritt 4: Ausführen ===
  
 Nun können wir unser Programm ausführen: Nun können wir unser Programm ausführen:
Zeile 268: Zeile 291:
 ``` ```
  
-### Makefile+==== - Makefile ====
  
 Grosse Projekte können sehr schnell aus sehr vielen einzelnen Files bestehen. Da jeweils alle dem Compiler übergeben werden müssen (`gcc -o main file1.cpp file2.cpp file3.cpp ...`), kann dies ziemlich mühsam werden. Hier kann ein Makefile helfen, siehe z.B. hier https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html#zz-2. Grosse Projekte können sehr schnell aus sehr vielen einzelnen Files bestehen. Da jeweils alle dem Compiler übergeben werden müssen (`gcc -o main file1.cpp file2.cpp file3.cpp ...`), kann dies ziemlich mühsam werden. Hier kann ein Makefile helfen, siehe z.B. hier https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html#zz-2.
Zeile 291: Zeile 314:
     rm *.o main     rm *.o main
 </code> </code>
 +
 +Eine etwas 'professionellere' Variante ist das folgende Makefile:
 +<code default makefile>
 +# Definiere Variablen für Compiler, Flags und ausfuehrbare Datei
 +CXX = g++
 +CXXFLAGS = -g -Wall
 +EXEC = main
 +
 +# AUFBAU
 +# Ziel: Abhaengigkeiten
 +#   Befehl
 +
 +${EXEC}: prog.o calc.o # wenn prog.o oder calc.o veraendert wurden -> erstelle Ausfuehrbare Datei main neu, indem der Befehl unten (g++ ...) ausgefuehrt wird 
 +    ${CXX} ${CXXFLAGS} -o ${EXEC} prog.o calc.o
 +
 +prog.o: prog.cpp calc.h # wenn prog.cpp oder calc.h veraendert wurden -> prog.o neu erstellen
 +    ${CXX} ${CXXFLAGS} -c prog.cpp
 +
 +calc.o: calc.cpp calc.h # analog
 +    ${CXX} ${CXXFLAGS} -c calc.cpp
 +
 +clean: # mit 'make clean', loesche alle .o und das main File
 +    rm *.o ${EXEC}
 +</code>
 +
 +Das Makefile kannst du dann mit folgenden Befehlen verwenden:
 +```
 +# ausführbare Datei erstellen (Kompilieren usw.)
 +make
 +# ausführen
 +./main
 +# main und .o Dateien löschen
 +make clean
 +```
  
  • talit/cpp.1602972591.txt.gz
  • Zuletzt geändert: 2020-10-17 22:09
  • von sca