C++-Programmierung/ Einführung zum Buch

Aus Wikibooks
Wechseln zu: Navigation, Suche
Einführung zum Buch
Panthera tigris altaica 13 - Buffalo Zoo.jpg

Zielgruppe:

Alle die das Buch lesen wollen und/oder sich für Hintergrundinformationen über C++ interessieren.

Lernziel:
Das lesen dieses Buches.


Wie lese ich dieses Buch? [Bearbeiten]

Egal, ob Sie schon C++ können, eine andere Programmiersprache beherrschen oder kompletter Programmieranfänger sind. Wenn Sie in C++ programmieren wollen, werden Sie mit diesem Buch etwas anfangen können. Es steht Ihnen frei, das Buch ganz normal von Anfang an zu lesen oder sich die Kapitel herauszupicken, die Sie interessieren. Allerdings sollten Sie beim Herauspicken darauf achten, dass Sie den Stoff der vorherigen Kapitel beherrschen, andernfalls werden Sie wahrscheinlich Schwierigkeiten haben, das Kapitel Ihres Interesses zu verstehen.

Dieses Buch gliedert sich in verschiedene Abschnitte, von denen jeder einen eigenen Schwierigkeitsgrad und entsprechend eine eigene Zielgruppe hat. Die meisten Abschnitte vermitteln Wissen über C++ oder sollen die praktische Anwendung zeigen, um das bisherige Wissen zu festigen. Andere weisen auf Besonderheiten und „Stolpersteine“ hin oder vermitteln Hintergrundwissen.

  • Jeder Abschnitt enthält eine Anzahl von Kapiteln, welche einen komplexeren Zusammenhang erklären. Die Abschnitte sind in sich abgeschlossen, setzen aber voraus, dass Sie den Stoff der vorherigen Abschnitte verstanden haben.
  • Am Ende jedes Kapitels stehen meistens ein paar Fragen und/oder Aufgaben, die Ihnen helfen sollen zu überprüfen, ob Sie verstanden haben, was im entsprechenden Kapitel stand. Die Antworten auf die Fragen lassen sich einfach ausklappen, für die Aufgaben gibt es je einen Verweis auf eine Seite mit einer Musterlösung. Diese Musterlösung ist natürlich nicht die einzige Variante, um die Aufgabe korrekt zu erfüllen, sie dient lediglich als Beispiel, wie Sie es machen könnten. Zu beachten ist allerdings, dass das im Kapitel erworbene Wissen genutzt werden sollte, um die Aufgabe zu erfüllen.
  • Jeder Abschnitt schließt mit einer Zusammenfassung ab, die das vermittelte Wissen kurz und bündig auf den Punkt bringt. Wer schnell etwas nachschlagen will, kann sich in der Regel an die Zusammenfassungen halten. Auf Abweichungen von dieser Regel wird explizit hingewiesen.

„Für Programmieranfänger“ ist der nächste Abschnitt. Wenn Sie schon in einer anderen Programmiersprache Programme geschrieben haben, können Sie diesen Abschnitt getrost überspringen. Es geht nicht speziell um C++, sondern eher darum, zu begreifen, was überhaupt eine Programmiersprache ist und wie man dem Rechner sagen kann, was er zu tun hat.

Wenn Sie eine andere Programmiersprache schon sehr sicher beherrschen, reicht es wahrscheinlich, wenn Sie von den nächsten Abschnitten nur die Zusammenfassungen lesen, aber es kann Ihnen in keinem Fall schaden, auch die kompletten Abschnitte zu lesen. Die Zusammenfassungen sollen Ihnen zwar einen groben Überblick geben, was in diesem Abschnitt vermittelt wurde, aber es ist nun einmal nicht möglich, zur gleichen Zeit kurz und vollständig zu sein.

Sofern Sie C++ schon sicher beherrschen, können Sie sich einfach ein Kapitel aussuchen, es lesen und wenn nötig, in einem früheren Kapitel nachschlagen. Umsteigern ist dieses Verfahren hingegen nicht zu empfehlen, weil C++ eben doch etwas anderes ist als die meisten anderen Programmiersprachen.

In jedem Fall hoffen wir, dass dieses Buch Ihnen hilft, Programmieren zu lernen und Ihre Fähigkeiten zu verbessern, aber vergessen Sie niemals, dass ein Buch nur eine Stütze sein kann. Programmieren lernt man durchs Programmieren!

Es war einmal… [Bearbeiten]

C++ wurde von Bjarne Stroustrup ab 1979 in den AT&T Bell Laboratories entwickelt. Ausgangspunkt waren Untersuchungen des UNIX-Betriebssystemkerns in Bezug auf verteiltes Rechnen.

Auf die Idee für eine neue Programmiersprache war Stroustrup schon durch Erfahrungen mit der Programmiersprache Simula im Rahmen seiner Doktorarbeit an der Cambridge University gekommen. Simula erschien zwar geeignet für den Einsatz in großen Software-Projekten, die Struktur der Sprache erschwerte aber die für viele praktische Anwendungen erforderliche Erzeugung hocheffizienter Programme. Demgegenüber ließen sich effiziente Programme zwar mit der Sprache BCPL schreiben, für große Projekte war BCPL aber wiederum ungeeignet.

Mit den Erfahrungen aus seiner Doktorarbeit erweiterte Stroustrup nun die Programmiersprache C um ein Klassenkonzept, für das die Sprache Simula-67 das primäre Vorbild war. Die Wahl fiel auf die Programmiersprache C, eine Mehrzwecksprache, die schnellen Code produzierte und einfach auf andere Plattformen zu portieren war. Als dem Betriebssystem UNIX beiliegende Sprache hatte C außerdem eine nicht unerhebliche Verbreitung. Zunächst fügte er der Sprache Klassen (mit Datenkapselung) hinzu, dann abgeleitete Klassen, ein strengeres Typsystem, Inline-Funktionen und Standard-Argumente.

Während Stroustrup „C with Classes“ („C mit Klassen“) entwickelte (woraus später C++ wurde), schrieb er auch cfront, einen Compiler, der aus C with Classes zunächst C-Code als Zwischenresultat erzeugte. Die erste kommerzielle Version von cfront erschien im Oktober 1985.

1983 wurde C with Classes in C++ umbenannt. Erweiterungen darin waren: virtuelle Funktionen, Überladen von Funktionsnamen und Operatoren, Referenzen, Konstanten, änderbare Freispeicherverwaltung und eine verbesserte Typüberprüfung. Die Möglichkeit von Kommentaren, die an das Zeilenende gebunden sind, wurde wieder aus BCPL übernommen (//).

1985 erschien die erste Version von C++, die eine wichtige Referenzversion darstellte, da die Sprache damals noch nicht standardisiert war. 1989 erschien die Version 2.0 von C++. Neu darin waren Mehrfachvererbung, abstrakte Klassen, statische Elementfunktionen, konstante Elementfunktionen und die Erweiterung des Schutzmodells um protected. 1990 erschien das Buch „The Annotated C++ Reference Manual“, das als Grundlage für den darauffolgenden Standardisierungsprozess diente.

Relativ spät wurden der Sprache Templates, Ausnahmen, Namensräume, neuartige Typumwandlungen und boolesche Typen hinzugefügt.

Im Zuge der Weiterentwicklung der Sprache C++ entstand auch eine gegenüber C erweiterte Standardbibliothek. Erste Ergänzung war die Stream-I/O-Bibliothek, die Ersatz für traditionelle C-Funktionen wie zum Beispiel printf() und scanf() bietet. Eine der wesentlichen Erweiterungen der Standardbibliothek kam später durch die Integration großer Teile der bei Hewlett-Packard entwickelten Standard Template Library (STL) hinzu.

Nach jahrelanger Arbeit wurde schließlich 1998 die endgültige Fassung der Sprache C++ (ISO/IEC 14882:1998) genormt. 2003 wurde ISO/IEC 14882:2003 verabschiedet, eine Nachbesserung der Norm von 1998.

Die vorhandenen Performance-Probleme der Sprache C++, die Rechenzeit und Speicherplatz betreffen, wurden auf hohem Niveau zusammen mit Lösungen im Technical Report ISO/IEC TR 18015:2006 diskutiert. Das Dokument ist zum Download von ISO freigegeben. (http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf)

Die aktuelle Version wurde am 11. Oktober 2011 als ISO/IEC 14882:2011 von der ISO veröffentlicht. Inoffiziell wird der Name C++11 verwendet, der Entwurf lief lange Zeit unter der inoffiziellen Bezeichnung C++0x. Die Entwürfe des C++-Standards können unter http://www.open-std.org/JTC1/SC22/WG21/ heruntergeladen werden. Das Dokument http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf stimmt mit C++11 bis auf minimale Änderungen überein.

Der offizielle Standard muss käuflich erworben werden, bei der ISO ist er für 238 Schweizer Franken zu haben, beim DIN zahlt man 659,60 €, beim ANSI steht der Preis bei 285 US-Doller, bzw. 761 US-Doller wenn man die britische Ausgabe kauft. Das INCITS verkauft ihn unter der Beizeichnung INCITS/ISO/IEC 14882-2012 für 30 US-Doller. Es lohnt sich also die Preise der unterschiedlichen Herausgeber bzw. Anbieter zu vergleichen.

Der Name „C++“[Bearbeiten]

Der Name ist eine Wortschöpfung von Rick Mascitti und wurde zum ersten Mal im Dezember 1983 benutzt. Der Name kommt von der Verbindung der Vorgängersprache C und dem Inkrement-Operator „++“, der den Wert einer Variable um eins erhöht.

Weiterentwicklung der Programmiersprache C++[Bearbeiten]

Um mit den aktuellen Entwicklungen der sich schnell verändernden Computer-Technik Schritt zu halten, aber auch zur Ausbesserung bekannter Schwächen, erarbeitet das C++-Standardisierungskomitee derzeit die nächste größere Revision von C++, die inoffiziell mit C++16 abgekürzt wird, worin die Ziffernfolge eine grobe Einschätzung des möglichen Erscheinungstermins andeuten soll. Derzeit ist 2016 als Termin im Gespräch, doch ist eine Verschiebung um wenige Jahre durchaus nicht unwahrscheinlich.

Erweiterung der Programmbibliothek[Bearbeiten]

Im April 2006 gab das C++-Standardisierungskomitee den so genannten ersten technischen Report (TR1) heraus, eine nichtnormative Ergänzung zur damals gültigen, 1998 definierten Bibliothek, mit der Erweiterungsvorschläge vor einer möglichen Übernahme in die C++-Standardbibliothek auf ihre Praxistauglichkeit hin untersucht werden sollen.

Enthalten sind im TR1 u.a. reguläre Ausdrücke, verschiedene intelligente Zeiger, ungeordnete assoziative Container, eine Zufallszahlenbibliothek, Hilfsmittel für die C++-Metaprogrammierung, Tupel sowie numerische und mathematische Bibliotheken. Die meisten dieser Erweiterungen stammen aus der Boost-Bibliothek, woraus sie mit minimalen Änderungen übernommen wurden. Außerdem sind viele Bibliothekserweiterungen der 1999 überarbeiteten Programmiersprache C (C99) in einer an C++ angepassten Form enthalten.

Mit Ausnahme der numerischen und mathematischen Bibliotheken wurde die Übernahme aller TR1-Erweiterungen in die aktuelle Sprachnorm C++11 vom C++-Standardisierungskomitee beschlossen.

In Vorbereitung auf den nächsten Standard wird die Erweiterung im Bereich der Netzwerke, des Dateisystems und der Verwendung von XML und möglicherweise auch HTML diskutiert.

Compiler [Bearbeiten]

Dieses Kapitel ist noch nicht vollständig Dann veröffentlicht doch wenigstens die unvollständige Variante, kann doch nicht sein das man im C++ Buch den Hinweis bekommt wenn man sich nicht sicher ist hier weiter zu lesen und dann kommt sowas !

Es ist ein 60%-Buch, also für "Konsumenten" sowieso noch völlig uninteressant. Leider befindet sich die Fortschrittsanzeige nur im Regal. Ein echter Systemfehler. Wer über z.B. C++ direkt zum Buch gelangt, wie du vielleicht, hat Pech gehabt ob der vergeudeten Zeit. Das schadet nachhaltig de.WBs Ansehen (bei en.WB ist man schlauer). Aber hier sind Verschönerungen und Vorlagenbasteleien wichtiger. --92.196.22.166 09:58, 28. Jun. 2014 (CEST)

Was passiert beim Übersetzen[Bearbeiten]

Der Präprozessor[Bearbeiten]

In C++ gibt es so wie bei C einen Präprozessor, der vor dem Lauf des Übersetzers gewisse Zeilen des Codes umformt. Das Ergebnis wird dann dem Übersetzer übergeben. Diese Zeilen beginnen mit einer Raute (Doppelkreuz) (#), gefolgt von einer Anweisung. Beispiele sind

    #include "Dateiname.Erweiterung"
    #include <Dateiname.Erweiterung>
    #define
    #ifdef
    #endif
    #pragma once

Der Präprozessor führt Ersetzungen auf Textbasis aus, das heißt, es findet keinerlei kontextabhängige Prüfung statt, ob dabei korrektes C++ entsteht.

Übersetzer[Bearbeiten]

Der Übersetzer (engl. compiler) ist das Programm, das aus dem vom Präprozessor erzeugten C++-Code Objektdateien erzeugt. Diese Dateien beinhalten betriebssystemnahen Maschinencode, der aber auch auf externe Funktionen zugreift, wobei extern bedeutet, dass sie nicht in derselben Datei vorhanden sind. Sollten syntaktische Fehler im Code enthalten sein, gibt der Übersetzer mehr oder weniger präzise Fehlermeldungen aus – je nachdem, von was für einem Hersteller er stammt, welcher Modus eingestellt ist, usw. Der Fehlerberichtmodus bestimmt, welche Fehlermeldungen ausgegeben werden. Bei zurückhaltender Einstellung werden nur Fehlermeldungen ausgegeben. Wird die Ausgabemenge durch einen andern Modus erweitert, werden auch Warnungen und dann auch Hinweise hinzugefügt, die auf einen eventuellen Fehler verweisen.

Der Bindelader[Bearbeiten]

Der Bindelader (engl. linker, selten auch Binder genannt) bindet die vom Übersetzer gelieferten Objektdateien zu einem ausführbaren Code, indem alle Verweise auf externe oder auf Betriebssystemfunktionen aufgelöst werden. Sollte diese Auflösung nicht gelingen, meldet der Binder, dass versucht wird, auf unauffindbare Funktionen oder Objekte zuzugreifen.

Hilfsmittel[Bearbeiten]

  1. Compiler Liste (mit Betriebssystem)
  2. IDE Liste (mit Betriebssystem und möglichen Compilern)

Die GCC[Bearbeiten]

GCC steht für Gnu Compiler Collection und ist eine Sammlung von freien Compilern. GCC stellt neben dem C++-Compiler namens "g++" noch viele andere Compiler für verschiedene Sprachen bereit. Der C-Compiler ist etwa gcc und der Java-Compiler heißt gcj.

GCC steht unter der GNU General Public License (GNU GPL), das heißt, GCC ist Freie Software und jeder ist berechtigt, den Quellcode einzusehen, zu verändern und natürlich auch GCC zu verwenden. Da GCC auf sehr viele Plattformen portiert wurde und unter nahezu allen Betriebssystemen verfügbar ist, eignet er sich prächtig, um ihn in einem Buch wie diesem zu verwenden.

Auf fast allen GNU/Linux-, Unix- und unixartigen Systemen ist GCC schon standardmäßig installiert. Falls nicht, können Sie ihn mit dem Paketmanager Ihrer Distribution nachinstallieren oder ihn von gcc.gnu.org herunterladen und manuell installieren. Auf Windows können Sie MinGW (eine Portierung von GCC) verwenden. Sie ist zwar nicht so aktuell wie die originale GCC-Version, aber für den Anfang immer noch ausreichend. Alternativ können Sie GCC auf Windows auch über Cygwin nutzen.

Aber jetzt ist Schluss mit der Theorie. Schauen wir uns erst einmal an, wie g++ benutzt wird. Im folgenden wird angenommen, dass eine Datei mit dem Namen prog.cpp vorhanden ist. In dieser Datei könnte zum Beispiel folgendes stehen:

Crystal Clear app terminal.png
#include <iostream>

using namespace std;

int main(){
    cout << "Hallo Welt\n";
}
Crystal Clear app kscreensaver.png
Ausgabe:
Hallo Welt

Dieses Programm müssen Sie noch nicht verstehen, im Kapitel Hallo, du schöne Welt! wird es erklärt. Nun geben Sie auf der Kommandozeile (GNU/Linux: Shell, Windows: Eingabeaufforderung) folgendes ein:

g++ prog.cpp

g++ ist der Name des Programms, welches aufgerufen wird, also der Compiler g++. prog.cpp ist der Name der Datei, die kompiliert werden soll. Wenn Sie diesen Befehl ausführen, sehen Sie entweder Fehlermeldungen auf dem Bildschirm, oder aber Sie bekommen eine Datei mit dem Namen a.out. Manchmal bekommen Sie auch sogenannte „warnings“, also Warnungen. Bei diesen Warnungen wird der Code zwar kompiliert, aber Sie sollten versuchen, warnungsfreie Programme zu schreiben. Ein Beispiel für eine Warnung könnte z.B. sein:

g++ prog.cpp
prog.cpp: In function `int main()':
prog.cpp:17: warning: comparison between signed and unsigned integer expressions

In diesem Beispiel würde die Warnung bedeuten, dass wir eine Zahl ohne Vorzeichen (unsigned) und eine mit Vorzeichen (signed) vergleichen, und zwar innerhalb der Funktion `int main()', genauer gesagt in Zeile 17. Was unsigned und signed ist, erfahren Sie im Kapitel Variablen, Konstanten und ihre Datentypen.

Es gibt auch einige, zum Teil hilfreiche Warnungen, die nicht angezeigt werden. Um diese zu sehen, müssen Sie die Option -Wall hinzufügen.

g++ -Wall prog.cpp

Um sich noch mehr Warnungen anzeigen zu lassen (-Wall zeigt auch nicht alle), können Sie auch noch -Wextra benutzen:

g++ -Wall -Wextra prog.cpp

Es wird empfohlen, diese Möglichkeit zu nutzen, vor allem wenn Sie auf der Suche nach Fehlern in Ihrem Programm sind.

Möchten Sie, dass das fertige Programm einen anderen Namen als a.out hat, so können Sie es natürlich jedesmal umbenennen. Dies ist aber umständlich und somit nicht zu empfehlen. Ein viel eleganterer Weg ist das Benutzen der Option -o.

g++ -o tollername prog.cpp

Der Dateiname nach der Option -o gibt an, in welche Datei das kompilierte Programm gespeichert werden soll. So erhalten Sie in diesem Beispiel die ausführbare Datei tollername.

Sollten Sie sich einmal nicht mehr erinnern, was eine bestimmte Funktion bewirkte oder wie sie hieß, so können Sie g++ einfach nur mit der Option --help aufrufen.

g++ --help

g++ gibt dann eine kurze Auflistung der Optionen aus. Wer gerne eine detailliertere Version hätte, kann unter GNU/Linux auch das Manualprogramm „man“ benutzen:

man g++

Ausführlichere und übersichtlichere Dokumentation, die nicht nur die Kommandozeilenoptionen vorstellt, sind im Dokumentationssystem info zu finden, das auf vielen GNU/Linux- und BSD-Systemen installiert ist:

info g++

Für Fortgeschrittenere[Bearbeiten]

Jetzt sollten Sie erst einmal den Rest des Kapitels überspringen und mit einigen der folgenden Buchkapitel weitermachen, denn für den Rest ist ein wenig Vorwissen sehr hilfreich. Sobald Sie mit den ersten paar Kapiteln fertig sind, können Sie hierher zurückkehren und den Rest lesen.

Was passiert überhaupt, wenn Sie g++ aufrufen? Nun, als erstes wird der Code vom Präprozessor durchgeschaut und bearbeitet. (Natürlich bleibt Ihre Quelldatei, wie sie ist.) Dabei werden beispielsweise Makros ersetzt und Kommentare gelöscht. Dieser bearbeitete Code wird dann vom Compiler in die Assemblersprache übersetzt. Die Assemblersprache ist auch eine Programmiersprache, welche aber nur die Maschinensprache so darstellt, dass ein Mensch sie (leichter) lesen kann. Schließlich wird diese Assemblersprache von einem Assembler in Maschinencode umgewandelt. Zum Schluss wird noch der Linker aufgerufen, der die einzelnen Programmdateien und die benutzten Bibliotheken "verbindet".

Darum, dass dies alles in korrekter Reihenfolge richtig ausgeführt wird, brauchen Sie sich nicht zu kümmern; g++ erledigt das alles für Sie. Allerdings kann es manchmal nützlich sein, dass das Programm noch nicht gelinkt wird, etwa wenn Sie mehrere Quelldateien haben. Dann kann man einfach dem g++ die Option -c mitgeben.

g++ -c -o prog.o prog.cpp

Durch diesen Aufruf erhalten wir eine Datei prog.o, die zwar kompiliert und assembliert, aber noch nicht gelinkt ist. Deswegen wurde die Datei auch prog.o genannt, da ein kompiliertes und assembliertes, aber nicht gelinktes Programm als Objektdatei vorliegt. Objektdateien bekommen üblicherweise die Endung *.o. Ohne die -o Option hätten Sie möglicherweise eine Datei gleichen Namens erhalten, aber das ist nicht absolut sicher. Es ist besser den Namen der Ausgabedatei immer mit anzugeben; so können Sie sicher sein, dass die ausgegeben Dateien auch wirklich den von Ihnen erwarteten Namen haben.

Bei g++ gibt es Unmengen von Optionen, mit denen Sie fast alles kontrollieren können. So gibt es natürlich auch eine Option, durch die kompiliert, aber nicht assembliert wird. Diese Option heißt -S.

g++ -S prog.cpp

Diese Option wird allerdings fast nie benötigt, es sei denn Sie interessieren sich dafür, wie Ihr Compiler Ihren Code in Assembler umsetzt. Die Option -E ist schon nützlicher. Mit ihr wird nur der Präprozessor ausgeführt:

g++ -E prog.cpp

So können Sie z. B. sehen, ob mit den Makros alles ordnungsgemäß geklappt hat oder die Headerdateien eventuell in einer von Ihnen unerwarteten Reihenfolge inkludiert wurden. Eine Warnung sollen Sie hier aber mit auf den Weg bekommen. Wenn der Präprozessor durchgelaufen ist, stehen auch alle mittels #include eingebundenen Headerdateien der Standardbibliothek mit im Quelltext, die Ausgabe kann also ziemlich lang werden. Allein das Einbinden von iostream produziert bei g++ 4.6.3 knapp 19 000 Zeilen Code. Welche Zeit es in Anspruch nimmt, den Quellcode nach dem Übersetzen in Assembler (Option -S) zu lesen, dürfte damit geklärt sein.

Sie sollten auch die Option -ansi kennen. Da g++ einige C++ Erweiterungen beinhaltet, die nicht im C++-Standard definiert sind oder sogar mit ihm im Konflikt stehen, ist es nützlich, diese Option zu verwenden, wenn Sie ausschließlich mit Standard-C++ arbeiten wollen. In der Regel ist das zu empfehlen, da sich solcher Code viel leichter auf andere Compiler portieren lässt. Im Idealfall müssten Sie gar keine Änderungen mehr vornehmen. Da aber weder g++ noch irgendein anderer Compiler absolut standardkonform sind, ist das selten der Fall. Ein Negativbeispiel für standardkonforme Compiler kommt immer mal wieder aus Redmond. Die dort ansässige Firma produziert in der Regel Produkte, die zu ihren selbstdefinierten Standards in einer bestimmten Version (also nicht mal untereinander) kompatibel sind. Beschweren Sie sich bitte nicht, wenn einige Programmbeispiele mit deren Compiler nicht kompiliert werden. Der Fairness halber soll trotzdem angemerkt werden, dass langsam aber doch sicher Besserung in Sicht ist.

g++ -ansi -o prog prog.cpp

Dies bewirkt, dass diese nicht standardkonformen Erweiterungen des g++-Compilers abgeschaltet werden. Solcher Code ist in der Regel die bessere Wahl, da er auch in Zukunft, wenn es neue Compiler oder Compiler-Versionen geben wird, noch mit ihnen übersetzt werden kann.

Möchten Sie eine Warnung erhalten, wenn nicht standardkonforme Erweiterungen von g++ verwendet werden, dann nutzen Sie die Option -pedantic:

g++ -pedantic -o prog prog.cpp

Um die Optimierung zuzuschalten, nutzen Sie die Option -Ox, wobei das x für eine Zahl von 1 bis 3 steht. 3 bedeutet stärkste Optimierung.

g++ -O3 -o prog prog.cpp

Programme, die mit Optimierung übersetzt wurden, sind kleiner und laufen schneller. Der Nachteil besteht in der höheren Zeit, welche für die Übersetzung an sich benötigt wird. Daher sollten Sie die Optimierung nur zuschalten, wenn Sie eine Programmversion erstellen, die Sie auch benutzen möchten. Beim Austesten während der Entwicklung ist es besser, ohne Optimierung zu arbeiten, da häufig kompiliert wird. Eine lange Wartezeit, nur um dann einen Programmdurchlauf zu machen, ist schlicht nervtötend.

Externe Bibliotheken benutzen[Bearbeiten]

Die C++-Standardbibliothek ist zwar eine wohl durchdachte und vielfach bewährte Bibliothek für Ihre Programme; allerdings ist sie kein Wundermittel für alle Probleme. Um auch andere Bibliotheken mit einem Programm nutzen zu können, bietet der Compiler spezielle Optionen an.

Headerdateien finden[Bearbeiten]

Damit die Quelldateien, die die externe Bibliothek benutzen, übersetzt werden können, muss der Präprozessor die Headerdateien finden. Mit dem Befehl cpp -v werden die Standardverzeichnisse ausgegeben, in denen nach Headerdateien gesucht wird. Befinden sich die Dateien der Bibliothek in einem anderen Verzeichnis, muss dieses mit der Option -I angegeben werden. Die imaginäre Bibliothek libfoo bietet z.B. eine Headerdatei foo.h im Verzeichnis /usr/include/libfoo an. Folgender Befehl wäre damit nötig:

g++ -I/usr/include/libfoo -o prog prog.cpp

Die Quelldatei kann die Headerdatei nun wie jede andere Datei der Standardbibliothek einbinden:

Crystal Clear app terminal.png
#include <foo.h>

Mit Bibliothek linken[Bearbeiten]

Es reicht aber noch nicht aus, dass die Headerdateien eingebunden werden können. Der Linker muss den compilierten Code der Quelldateien zusammen mit der Bibliothek linken. Dafür bietet der Compiler die Option -l an, die den Namen der Bibliothek benötigt. Die Zeichenkette lib kann weggelassen werden, aus libfoo wird also einfach nur foo:

 g++ -I/usr/include/libfoo -lfoo -o prog prog.cpp

Makefiles[Bearbeiten]

Was ist make?[Bearbeiten]

Bei make handelt es sich um ein Werkzeug, mit dem man die Abhängigkeiten eines Build Prozesses auflösen kann. Dieses Stück Software ist schon sehr alt und in unterschiedlichsten Implementierungen verfügbar, die verbreitesten sind wohl GNU make und BSD make. Leider sind die verschiedenen Varianten untereinander nicht ganz kompatibel.

Makefiles per Hand erstellen[Bearbeiten]

make kann sehr viel mehr, als hier beschrieben werden könnte, es folgt daher lediglich eine kurze Erläuterung, um was es eigentlich geht. In einem Makefile lassen sich Regeln beschreiben, wie bestimmte "Targets" (Ziele) erstellt werden können. Diese können von anderen Zielen oder Dateien abhängen.

Beispielsweise erstellt man eine Objektdatei aus einer Sourcedatei, indem man sie kompiliert. Dazu muss aber natürlich die Sourcedatei vorhanden sein. Eine solche Regel könnte zum Beispiel so aussehen:

hello.o: hello.c
    $(CC) -c $(CFLAGS) hello.c

Die erste Zeile besagt, dass zum Erstellen von hello.o die Datei hello.c benötigt wird. Die Zweite sagt aus, wie das Erstellen von hello.o zu bewerkstelligen ist. Variablen werden mit $ eingeleitet. So beinhaltet zum Beispiel $(CC) in der Regel den Namen des C Compilers.

Derartige Regeln kann man auch mit Wildcards versehen, so kann man eine Regel erstellen, mit der man ausdrücken kann, wie generell aus einer *.c eine *.o Datei zu erstellen ist:

%.o: %.c
    $(CC) -c $(CFLAGS) $< 

Dabei steht die spezielle Variable $< für den Namen der tatsächlichen Source Datei, wie zum Beispiel hello.c.


Beispiel:

CC = gcc
OBJECTS = cbg.o
LIBS = -lcurl
CFLAGS = -Wall -O2
BINDIR = $(DESTDIR)/usr/bin
NAME = cbg
cbg: $(OBJECTS)
   $(CC) -o $(NAME) $(OBJECTS) $(LIBS)
%.o: %.c
   $(CC) -c $(CFLAGS) $<
install:
   install --mode=755 $(NAME) $(BINDIR)/
clean:
   rm *.o $(NAME)
uninstall:
   rm $(BINDIR)/$(NAME) 

Damit ist es nun möglich, die einzelnen Ziele zu erstellen:

make install
make clean
make uninstall 

Wird kein Ziel angegeben, so wird das erste Ziel erstellt, in obigen Beispiel also cbg.

Automake[Bearbeiten]

Boost Build[Bearbeiten]

Eine sehr gute alternative zu Makefiles. http://www.boost.org/doc/tools/build/index.html

GUIs und C++ [Bearbeiten]

Was ist ein GUI?[Bearbeiten]

GUI kommt vom englischen „Graphical User Interface“, was soviel heißt wie „Graphische Benutzerschnittstelle“. Grob gesagt ist es das, was der Benutzer von den meisten Programmen zu sehen bekommt. Also: Die Menüleiste, Textfelder, Buttons u.s.w.

Weiterhin gibt es natürlich noch das „Command Line Interface“ (kurz CLI, zu Deutsch "Kommandozeilenschnittstelle"), das vielen als Fenster mit schwarzem Hintergrund und weißer Schrift bekannt ist.

C++ und GUIs[Bearbeiten]

C++ bringt von Haus aus kein GUI mit, da es als hardwarenahe plattformunabhängige Sprache erstellt wurde und GUIs stark vom verwendeten Betriebssystem abhängen. Dieser „Mangel“ könnte einige Neueinsteiger vielleicht auf den ersten Blick abschrecken, da sie sich einen Einstieg in C++ oder gar in die gesamte Programmierung mit vielen Buttons, Textfeldern, Statusanzeigen und Menüeintragen erhofft haben.

Wer jedoch einmal damit angefangen hat, kleinere Programme zu schreiben, wird schnell merken, dass der Reiz hier nicht von bunten Farben und blinkenden Symbolen ausgeht. Ganz im Gegenteil. Gerade für den Anfänger ist es am besten, wenn die eigentliche Funktion nicht durch Tonnen von "Design-Code" überdeckt und unleserlich gemacht wird. Hat man erst einmal die Grundlagen erlernt, so ist es nicht schwer auch ansprechende Oberflächen zu erstellen.

Es gibt eine ganze Reihe von Bibliotheken, die eine weitgehend plattformübergreifende Programmierung mit C++ als Sprache ermöglichen. Aber auch die Programmierung über die API (für engl. „application programming interface“, deutsch: „Schnittstelle zur Anwendungsprogrammierung“) des spezifischen Betriebssystems ist natürlich möglich.

Einsatz von GUI[Bearbeiten]

Sobald man mit C++ dann doch ein GUI programmieren will, sollte auf externe Bibliotheken zurückgegriffen werden. Alle GUIs erfordern ein Verständnis der C++ Grundlagen. Nachfolgend sind einige Bibliotheken zur GUI-Programmierung aufgelistet. Viele der Bibliotheken lassen sich auch mit anderen Programmiersprachen einsetzen.

Qt[Bearbeiten]

Qt ist eine leistungsstarke plattformübergreifende Klassenbibliothek mit Meta-Object Compiler (gennant: moc), die von der norwegischen Firma Trolltech entwickelt wurde. Trolltech wurde 2008 von Nokia übernommen, welches jedoch wirtschaftliche Schwierigkeiten hatte und in der Folge Qt 2011 an das finnische Softwareunternehmen Digia verkaufte.

Die Entwicklung wird inzwischen vom Qt Project vorangetrieben, so dass jeder sich daran beteiligen kann. Die Klassenbibliothek ist unter der GNU General Public License (GPL) und der GNU Lesser General Public License (LGPL) lizenziert. Es gibt außerdem eine proprietäre Lizenz von Digia, die allerdings lediglich zusätzlichen technischen Support beinhaltet.

Speziell aufgrund der Veränderungen, die mit Qt 5 und C++11 Einzug in das Framework halten, ist Qt eines der mächtigsten Bibliotheken für C++. Ein weiterer Vorteil von Qt ist die vollständig freie Entwicklungsumgebung Qt Creator, die insbesondere Anfängern das Leben leichter macht.

Symbol redirect vote.svg
Buchempfehlung

Das Buch „Qt für C++-Anfänger“ gibt einen Einstieg in die Programmierung mit Qt. Es behandelt nicht viele Themen und ist somit wirklich nur zum Kennenlernen des Frameworks geeignet. Dafür sind die vorhandenen Seiten aber auch gut gefüllt.

GTK+[Bearbeiten]

Das GIMP-Toolkit (abgekürzt: GTK+) ist eine freie Komponentenbibliothek, die in C geschrieben ist und unter der GNU Lesser General Public License (LGPL) steht. Um dieses Framework in C++ zu nutzen gibt es ein Framework namens Gtkmm. Wie Qt ist es für viele Plattformen verfügbar.

wxWidgets[Bearbeiten]

wxWidgets ist ein auf C++ basierendes Open-Source-Framework zur plattformunabhängigen Entwicklung von Anwendungen mit grafischer Benutzeroberfläche (GUI). Die wxWidgets-Lizenz ist eine leicht modifizierte LGPL und erlaubt daher ebenfalls die freie Verwendung in proprietärer und freier Software und den weiteren Vertrieb unter einer selbst gewählten Lizenz.

MFC[Bearbeiten]

Die Microsoft Foundation Classes (MFC) sind ein C++ Framework, vor allem zur GUI-Programmierung unter Microsoft Windows. Es verwendet Entwurfsmuster, insbesondere Document-View (Model-View-Controller), Singleton, Bridge und Observer, um Funktionalität der Windows-API zu kapseln. Außerdem gibt es eine enorme Anzahl an Hilfsmakros zur Unterstützung bei RTTI („Runtime Type Information“), Nachrichtenbehandlung, dynamischer Instanziierung etc.. Da sie seit 1992 in jeder -nicht Express- Version von Microsoft Visual C++ enthalten sind ist ihre Verbreitung auf der Windows-Plattform sehr hoch. Die Verwendung ist an eine kommerzielle Lizenz gebunden, den Besitz einer kostenpflichtigen Version von Visual C++, die MFC-Laufzeitumgebung ist kostenlos. Für die GUI-Entwicklung mit C++ -nicht C++/CLI- auf Windows sind die MFC das am weitesten verbreitete Framework das direkt auf der Windows-API aufsetzt.

Konventionen [Bearbeiten]

Konventionen sind Regeln, die in der Programmierung verwendet werden, um die Übersichtlichkeit des Quellcodes zu erhöhen. Diese Regeln werden vom Programmierer festgelegt und entsprechend werden Sie, wenn Sie sich verschiedene Projekte ansehen, sehr wahrscheinlich auch unterschiedliche Konventionen erkennen. Im Laufe des Lebens entwickelt eigentlich jeder Programmierer seine eigenen Konventionen. Daher ist es wichtig, sich auf eine Liste von Konventionen zu einigen, wenn man in einem Projekt mit mehreren Entwicklern zusammenarbeitet. Da dieses Buch nicht ausschließlich von einem Autor geschrieben wird, handelt es sich auch hierbei um ein solches Projekt.

Innerhalb des Buches wird an verschiedenen Stellen auf einzelne Konventionen eingegangen. Dabei werden auch alternative Möglichkeiten zu den hier verwendeten aufgeführt. Wir werden in diesem Kapitel versuchen, eine vollständige Liste der in diesem Buch verwendeten Konventionen aufzustellen. Der unerfahrene Leser wird damit nicht viel anfangen können und kann den Rest des Kapitels daher überspringen, um später darauf zurück zu kommen. Für Co-Autoren sollte die Liste jedoch von großem Wert sein.

  • Bezeichner (selbstvergebene Namen, engl. identifier) werden vollständig klein geschrieben. Besteht ein Bezeichner aus mehreren Wörtern, so werden diese mit Unterstrich getrennt.
    • Ausnahme: Templateparameter (Vorlagenparameter). Diese beginnen mit einem Großbuchstaben und die Trennung erfolgt wiederum mit einem Großbuchstaben und ohne Unterstrich.
  • Die Namen für Quell- (.cpp) und Headerdateien (.hpp) sowie für Unterverzeichnisse folgen den Konventionen für Bezeichner.
  • Eine Einrückung besteht aus vier Leerzeichen.
  • Eingebaute Datentypen werden abgekürzt (long statt signed long int), Ausnahme: unsigned int und signed int, Achtung: char ist nicht zwingend gleich signed char!
  • Im globalen Namensraum werden keine using-Direktiven verwendet. Eigentlich sollten im globalen Namensraum ausschließlich benannte Namensräume stehen. Das würde im Buch jedoch den Beispielcode aufblähen. Daher verzichten wir ausnahmsweise darauf.
  • Bezeichner aus anderen Namensräumen sollten per using-Deklaration eingefügt werden. Das spart Tipparbeit und hat in Zusammenhang mit Templates (Vorlagen) auch einen technisch sinnvollen Effekt (argumentabhängige Namenssuche). Da dies zwar in der breite Platz spart, jedoch zusätzliche Zeilen benötigt, wird in unbedenklichen Fällen innerhalb des Buches direkt zugegriffen. Dies gilt insbesondere für std::cout, std::cin und std::endl.
  • Es werden nur Zeilenkommentare (// Kommentar) verwendet. C-Kommentare (/* Kommentar */) sind tabu.
  • const steht immer rechts von dem, zu dem es gehört. (int const statt const int)
  • Templatetypparameter werden durch typename gekennzeichnet, nicht durch class.
  • Öffnende geschweifte Klammern stehen nicht auf einer eigenen Zeile, sondern am Zeilenende. Sie werden nicht durch Leerzeichen getrennt.
  • Schließende Klammern stehen auf der gleichen Einrückungsebene, wie der Ausdruck der korrespondierenden öffnenden Klammer.
  • Es wird maximal eine Anweisung (engl. statement) pro Zeile geschrieben.
  • Wird eine einzelne Anweisung nach einem if usw. auf eine neue Zeile geschrieben, wird sie in einen Block gepackt, sonst nicht.
  • Lange Zeilen werden umgebrochen, wobei die umgebrochenen Zeilen um eine Ebene eingerückt sind.
    • Funktionsaufrufe werden so umgebrochen, dass die runden Klammern wie Geschweifte und die einzelnen Parameter wie Anweisungen (jeder auf eine eigene Zeile) behandelt werden. Dies bedeutet insbesondere, das die schließende Klammer auf der gleichen Einrückungsebene steht, wie der Funktionsaufruf.
    • Mit Templateinstantiierungen wird analog zu Funktionsaufrufen verfahren.
  • Mehrere Variablen werden nur dann gemeinsam deklariert, wenn sie eine identischen Typ haben. (int a, *b; ist verboten.)
  • Die Variablendefinition erfolgt so spät wie möglich.
  • Klassen:
    • private- und protected-Variablen enden auf einen Unterstrich.
    • private-Funktionen enden auf einen Unterstrich.
    • private, protected, public und friend stehen auf der gleichen Einrückungsebene wie class.
  • Wenn im Fließtext über Funktionen (Methode, Operatoren in Funktionsschreibweise) gesprochen wird, wird dies mit leeren Klammern hinter dem Funktionsnamen angedeutet.

Speziell für Autoren[Bearbeiten]

  • Die Vorlagen von C++-Programmierung/ Vorlagen sind zu verwenden.
  • Die Vorlage „cpp“ für Fließtext-C++ wird mit einem kleinen „c“ am Anfang geschrieben. Dies ist weniger Tipparbeit und neue Autoren verwirrt eine unterschiedliche Verwendung möglicherweise.
  • #pragma once wird in diesem Buch nicht verwendet, weil das nicht im Standard steht.
  • Quelltext-Blöcke sollten pro Zeile maximal 100 Zeichen umfassen.
  • Einige Worte werden auf Englisch belassen. Die folgende Liste versucht alle Aufzuführen. Bei umfangreichen Änderungen eines nicht-aufgeführten Wortes, ist vorweg beim Hauptautor (Benutzer:Prog) nachzufragen:
    • Compiler (compilergeneriert, Compilierfehler, kompilieren oder übersetzen)
    • Code (alternativ Quelltext)