From 6be11a3b47395c6b14f2dc0b6469f83146372c58 Mon Sep 17 00:00:00 2001 From: LamdaLamdaLamda <25778959+LamdaLamdaLamda@users.noreply.github.com> Date: Mon, 20 May 2019 13:14:17 +0200 Subject: [C++/de] added. (#3527) * Added [C++/de] * [C++/de] filename fixed. * [C++/de] language code in filename added * [C++/de] file duplicate removed --- de-de/c++-de.html.markdown | 1160 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1160 insertions(+) create mode 100644 de-de/c++-de.html.markdown (limited to 'de-de/c++-de.html.markdown') diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown new file mode 100644 index 00000000..23cc26a8 --- /dev/null +++ b/de-de/c++-de.html.markdown @@ -0,0 +1,1160 @@ +--- +language: c++ +filename: learncpp-de.cpp +contributors: + - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Connor Waters", "http://github.com/connorwaters"] + - ["Ankush Goyal", "http://github.com/ankushg07"] + - ["Jatin Dhankhar", "https://github.com/jatindhankhar"] + - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"] +--- + +C++ ist eine Systemprogrammiersprache die, + +[laut dem Begründer Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote) +entworfen wurde um, + +- "besseres C" zu sein +- Datenabstraktion zu unterstützen +- Objektorientierung zu unterstützen +- generische Programmierung zu unterstützen + +Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein. +Sie ist weit verbeitet, weil sie in Maschinen-Code compiliert, welches direkt vom Prozessor ausgeführt +werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig +High-Level-Features wie generics, exceptions und Klassen enthält. (wie C) +Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der +weitverbreitesten Programmiersprachen. + +```c++ +////////////////// +// Vergleich zu C +////////////////// + +// C++ ist fast eine Untermenge von C and teilt sich grundsätzlich den +// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen. + +// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und +// einen Ineteger als Rückgabetyp besitzt. +// Dieser Wert fungiert als Beendigungsstatus des Programms. +// Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen +int main(int argc, char** argv) +{ + // Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben + // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style + // strings (char*), welche die Argumente repräsentieren. + // Das erste Argument ist der Name des Programms welches aufgerufen wird. + // Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem + // die Funktionssignatur "int main()" verwendet wird. + + // Ein Rückgabewert von 0 repräsentiert die erfolgreiche Ausführung. + return 0; +} + +// C++ unterscheidet sich in einigen Punkten: + +// In C++ sind Zeichen-Literale chars +sizeof('c') == sizeof(char) == 1 + +// In C sind Zeichen-Literale ints +sizeof('c') == sizeof(int) + +// C++ verwendet striktes prototyping +void func(); // Funktion ohne Argumente + +// In C +void func(); // Funktion mit beliebiger Anzahl von Argumenten + +// Verwende nullptr, anstatt von NULL!!! +int* ip = nullptr; + +// C standard headers sind in C++ verfügbar. +// C header enden mit .h, während +// C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden. + +// Die C++ Standard Version: +#include + +// Die C Standard Version: +#include + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +/////////////////////// +// Funktionsüberladung +/////////////////////// + +// C++ unterstützt Funktionsüberladung +// Jede Funktion kann unterschiedliche Parameter erhalten. +void print(char const* myString) +{ + printf("String %s\n", myString); +} + +void print(int myInt) +{ + printf("My int is %d", myInt); +} + +int main() +{ + print("Hello"); // Wird aufgelöst zu "void print(const char*)" + print(15); // Wird aufgelöst zu "void print(int)" +} + +///////////////////////////// +// Standard Funktionsargumente +///////////////////////////// + +// Argumente können per Standard für eine Funktion gesetzt werden, +// wenn diese beim Aufruf nicht bereitgestellt werden. + +void doSomethingWithInts(int a = 1, int b = 4) +{ + // führe Anweisungen mit "ints" aus. +} + +int main() +{ + doSomethingWithInts(); // a = 1, b = 4 + doSomethingWithInts(20); // a = 20, b = 4 + doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// Standard-Argumente müssen am Ende der Liste der Argumente stehen. +void invalidDeclaration(int a = 1, int b) // Fehler! +{ +} + + +///////////// +// Namespaces (Namesräume) +///////////// + +// Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen, +// Funktionen und andere Deklarationen zur Verfügung. +// Namespaces können geschachtelt werden. +namespace First +{ + namespace Nested + { + void foo() + { + printf("This is First::Nested::foo\n"); + } + } // Ende des Namespaces "Nested" +} // Ende des Namespaces "First" + +namespace Second +{ + void foo() + { + printf("This is Second::foo\n"); + } +} + +void foo() +{ + printf("This is global foo\n"); +} + +int main() +{ + // Fügt all Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope). + // "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus + // dem namespace foo oder darüberliegenden aufgerufen wird. + using namespace Second; + + Second::foo(); // Gibt "This is Second::foo" aus. + First::Nested::foo(); // Gibt "This is First::Nested::foo" aus. + ::foo(); // Gibt "This is global foo" aus. +} + +/////////////// +// Eingabe/Ausgabe +/////////////// + +// C++ verwendet für die Eingabe und Ausgabe streams. +// cin, cout und cerr repräsentieren stdin, stdout und stderr. +// << ist der Einfügeoperator und >> ist der Extraktionsoperator. + +#include // Include für Eingabe/Ausgabe (I/O) streams + +using namespace std; // Streams befinden sich im std namespace (standard library) + +int main() +{ + int myInt; + + // Ausgabe auf stdout (oder Terminal/Bildschirm) + cout << "Enter your favorite number:\n"; + + // Empfängt Eingabe + cin >> myInt; + + // cout kann ebenfalls formatiert werden + cout << "Your favorite number is " << myInt << "\n"; + // Gibt "Your favorite number is " aus + + cerr << "Used for error messages"; +} + +////////// +// Zeichenketten (Strings) +////////// + +// Strings in C++ sind Objekte und haben diverse member-functions +#include + +using namespace std; // Strings sind ebenfalls im namespace std (Standard Bibliothek) + +string myString = "Hello"; +string myOtherString = " World"; + +// + wird für das Anhängen von strings verwendet. +cout << myString + myOtherString; // "Hello World" + +cout << myString + " You"; // "Hello You" + +// C++ strings sind mutable. +myString.append(" Dog"); +cout << myString; // "Hello Dog" + + +///////////// +// Referenzen +///////////// + +// Zusätzlich zu Pointern, wie jene in C. +// C++ besitzt _Referenzen_. +// Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können +// und nicht Null sein können. +// Sie besitzen den selben Synthax wie Variablen. +// Für die Dereferenzierung ist kein * notwendig und +// & (die Adresse) wird nicht für die Zuweisung verwendet. + +using namespace std; + +string foo = "I am foo"; +string bar = "I am bar"; + + +string& fooRef = foo; // Erzeugt eine Referenz auf foo. +fooRef += ". Hi!"; // Verändert foo durch die Referenz +cout << fooRef; // Gibt "I am foo. Hi!" aus. + + +// Weist "fooRef" nicht erneut zu. Dies ist dasselbe, wie "foo = bar" und +// foo == "I am bar" +// nach dieser Zeile +cout << &fooRef << endl; // Gibt die Adresse von foo aus +fooRef = bar; +cout << &fooRef << endl; // Gibt ebenfalls die Adresse von foo aus +cout << fooRef; // Gibt "I am bar" aus + +// Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo + + +const string& barRef = bar; // Erzeugt konstante Referenz auf bar. +// Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden. + +barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden. + +// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an +// welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Was passiert nun in der zweiten Zeile: +// - ein String Objekt wird von tempObjectFun zurückgegeben +// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt. +// - das zurückgegebene Objekt wird zerstört +// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt +// wann immer eine Funktion ein Objekt zurückgibt. Zerstört werden diese am Ende der Auswertung des Ausdrucks +// (dies schreibt der Standard vor, aber Compiler sind berechtigt dieses Verhalten zu ändern. Siehe "return value optimization" +// für Details). Wie in diesem Code: +foo(bar(tempObjectFun())) + +// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben, +// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird. + +// Zurück zu Referenzen. Die Ausnahme, dass die "am Ende des Ausdrucks" Regel ist gültig, +// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, in welchem Fall das +// Leben auf den aktuellen Gültigkeitsbereich erweitert wird. + +void constReferenceTempObjectFun() { + // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion + const string& constRef = tempObjectFun(); + ... +} + +// Eine andere Art von Referenzen wird in C++11 eingeführt und ist speziell für +// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber +// Vorrechte bei der Auflösung. +void someFun(string& s) { ... } // Reguläre Referenz +void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt + +string foo; +someFun(foo); // Ruft die Funktion mit der regulären Referenz auf +someFun(tempObjectFun()); // Ruft die Funktion mit der temporären Referenz auf + +// Zum Beispiel existieren diese zwei Varianten von Konstruktoren für +// std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später +// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird +// als "move semantics" bezeichnet (bewegen eines Objekts in ein anderes in C++). + +///////////////////// +// Enumerations (Aufzählungstypen) +///////////////////// + +// Enums sind eine einfachere Art und Weise einen Wert einer Konstante zu zuweisen. +// Häufig wird dies verwendet, um den Code lesbarer zu gestalten bzw. zu visualisieren. +enum ECarTypes +{ + Sedan, + Hatchback, + SUV, + Wagon +}; + +ECarTypes GetPreferredCarType() +{ + return ECarTypes::Hatchback; +} + +// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zu zuweisen. Dies +// kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung +// zwischen Typen bzw. Konstanten. +enum ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialisierung von InputValue in eine Datei +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass + // es sich um ein enum handelt. + WriteByteToFile(InputCarType); +} + +// Nicht immer ist es gewünscht, dass enums zu einem Integer oder zu einem anderen +// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche +// nicht implizit umgewandelt wird. +enum class ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialisierung von InputValue in eine Datei +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // Wird nicht kompilieren, da ECarTypes ein "uint8_t" ist, da das enum + // als "enum class" deklariert wurde! + WriteByteToFile(InputCarType); +} + +////////////////////////////////////////// +// Klassen und objekorientierte Programmierung +////////////////////////////////////////// + +// Erstes Beispiel einer Klasse +#include + +// Deklaration einer Klasse. +// Klassen werden üblicherweise im header (.h oder .hpp) deklariert. +class Dog +{ + // Member Variablen und Funktionen sind private per default (standard). + std::string name; + int weight; + +// Alle nachfolgenden member sind "public" bis +// "private:" oder "protected:" auftritt. +public: + + // Standard Konstruktor + Dog(); + + // Member-Funktonensdeklaration (Implementierung folgt) + // Bemerkung: std::string statt der Verwendung von namespace std; + // "using namespace" sollte niemals in einem header verwendet werden. + void setName(const std::string& dogsName); + + void setWeight(int dogsWeight); + + // Funktionen, die Objekte nicht ändern sollte mit const deklariert werden. + // Funktionen müssen explizit als "virtual" deklariert werden, um in einer + // abgeleiteten Klassen überschrieben zu werden. + // Aus performance Gründen sind Funktionen nicht per default virtual. + virtual void print() const; + + // Funktionen können ebenfalls im class body definiert werden. + // Derart definierte Funktionen sind automatisch "inline". + void bark() const { std::cout << name << " barks!\n"; } + + // Neben Konstruktoren, bietet C++ Destruktoren. + // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder + // seinen Wertebereich verlässt. + // Dies ermöglicht mächtige Paradigmen, wie auch RAII. + // Destruktoren sollten virtual sein, wenn eine Klasse von ihr + // abgeleitet wird. Ist dieser nicht virtual, dann wird der + // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern + // das Objekt durch eine Referenz/Pointer der Basisklasse entfernt wird. + virtual ~Dog(); + +}; // Ein Semikolon schließt die Definition der Klasse ab. + +// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implmentiert. +Dog::Dog() +{ + std::cout << "A dog has been constructed\n"; +} + +// Objekte sollten als Referenz übergeben werden und wenn diese nicht +// verändert werden sollen, sollte das Objekt als const Referenz übergeben werden. +void Dog::setName(const std::string& dogsName) +{ + name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} + +// "Virtual" wird nur bei der Deklaration benötigt und nicht bei der Definition. +void Dog::print() const +{ + std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; +} + +Dog::~Dog() +{ + std::cout << "Goodbye " << name << "\n"; +} + +int main() +{ + Dog myDog; // Ausgabe: "A dog has been constructed" + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.print(); // Ausgabe: "Dog is Barkley and weighs 10 kg" + return 0; +} // Ausgabe: "Goodbye Barkley" + +// Vererbung: + +// Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse +// und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese +// nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter. +class OwnedDog : public Dog { + +public: + void setOwner(const std::string& dogsOwner); + + // Überschreibt das Verhalten der "print" Funktion für alle "OwnedDogs". + // Siehe: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping + // für eine grundlegende Einführung in "Subtype Polymorphismus". + // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die + // Methode der Basisklasse tatsächlich überschrieben wurde. + void print() const override; + +private: + std::string owner; +}; + +// Die zugehörige .cpp Datei +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // Ruft die "print" Funktion der Basisklasse auf. + std::cout << "Dog is owned by " << owner << "\n"; + // Ausgaben: "Dog is and weights " + // "Dog is owned by " +} + +////////////////////////////////////////// +// Initialisierung und Operatorüberladung +////////////////////////////////////////// + +// In C++ können Operatoren wie: +, -, *, / etc. überladen werden. +// Dies wird umgesetzt, indem eine entsprechende Funktion definiert wird, +// welche immer dann aufgerufen wird, sobald der Operator verwendet wird. +#include +using namespace std; + +class Point +{ +public: + // Member Variablen können mit einem default Wert initialisiert werden. + double x = 0; + double y = 0; + + // Definition des Standard Konstruktor, welcher nichts tut + // außer den Punkt auf den default Wert (0,0) zu setzen. + Point() { }; + + // Die nachfolgende Syntax ist bekannt als "initialization list" + // und ist eine gängige Art Klassen-Member zu initialisieren. + Point (double a, double b) : + x(a), + y(b) + { /* Außschließliche Initialisierung der Werte */ } + + // Überladung des "+" Operator. + Point operator+(const Point& rhs) const; + + // Überladung des "+=" Operator + Point& operator+=(const Point& rhs); + + // Sinnhaft wäre es an dieser Stelle den "-" und "-=" Operator + // ebenfalls zu überladen. +}; + +Point Point::operator+(const Point& rhs) const +{ + // Erzeugung eines neuen Punkts, welcher die Summe aus sich + // selbst und "rhs" bildet + return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () +{ + Point up (0,1); + Point right (1,0); + + // Ruft den + Operator mit den entsprechenden Parametern auf. + Point result = up + right; + // Ausgabe: "Result is upright (1,1)" + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +///////////////////// +// Templates +///////////////////// + +// Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren. +// Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können +// sie für funktionale Klassen verwendet werden. +// Tatsächlich bilden templates die Turing-Vollständigkeit +// (universelle Programmierbarkeit) ab. + + +// Zu Beginn ein einführendes Beispiel der generischen Programmierung. +// Die Definition einer Klasse bzw. Funktion, welche mit dem Typ T parametriert wird. +template +class Box +{ +public: + // T repräsentiert an dieser Stelle einen beliebigen Typen. + void insert(const T&) { ... } +}; + +// Während der Kompilierung generiert der Kompiler Kopien für jedes Template, wobei +// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte +// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template +// komplett im header definiert. + +// Erzeugung einer Template-Klasse auf dem stack: +Box intBox; + +// eine der zu erwartenden Verwendungen: +intBox.insert(123); + +// Verschachtelungen von Templates sind möglich. +Box > boxOfBox; +boxOfBox.insert(intBox); + +// Bis C++11 war es erforderlich ein Leerzeichen zwischen '>' einzufügen, +// andernfalls wurde es als '>>' geparsed (right shift). + +// Manchmal ist folgende Notation anzutreffen: +// template +// Das 'class' Schlüsselwort und das 'typename' Schlüsselwort +// sind fast identisch hinsichtlich der Funktionalität. Weitere +// Informationen auf: http://en.wikipedia.org/wiki/Typename + +// Eine template-Funktion: +template +void barkThreeTimes(const T& input) +{ + input.bark(); + input.bark(); + input.bark(); +} + +// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters +// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen +// prüfen. Somit funktioniert die zuvor definiert Funktion für jeden Typ 'T', die die +// const Methode 'bark' implementiert hat. + +Dog fluffy; +fluffy.setName("Fluffy") +barkThreeTimes(fluffy); // Gibt "Fluffy barks" dreimal aus. + +// Template Parameter müssen keine Klassen sein. +template +void printMessage() +{ + cout << "Learn C++ in " << Y << " minutes!" << endl; +} + +// Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden. +// Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht +// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die +// Funktion oder Klasse als template deklariert werden. +template<> +void printMessage<10>() +{ + cout << "Learn C++ faster in only 10 minutes!" << endl; +} + +printMessage<20>(); // Gibt "Learn C++ in 20 minutes!" aus. +printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus. + + +///////////////////// +// Ausnahme Behandlungen (Exception-Handling) +///////////////////// + +// Die Standard Bibliothek bietet einige Exceptions. +// Siehe: http://en.cppreference.com/w/cpp/error/exception. +// Grundsätzlich können alle Typen als Exception geworfen werden. +#include +#include + +// Alle Exceptions, die in dem "try" Block geworfen werden, können mittels +// "catch" abgefangen werden. +try +{ + // Exceptions sollten nicht auf dem heap mithilfe + // von "new" allokiert werden. + throw std::runtime_error("A problem occurred"); +} + +// Exceptions sollten als const Referenz abgefangen werden +// insofern diese Objekte sind. +catch (const std::exception& ex) +{ + std::cout << ex.what(); +} + +// Abfangen aller Exceptions, welche zuvor nicht abgefangen wurden. +catch (...) +{ + std::cout << "Unknown exception caught"; + throw; // Erneutes werfen der exception +} + +/////// +// RAII +/////// + +// RAII steht für "Resource Acquisition Is Initialization". +// Oft wird dies als eines der wichtigsten Paradigmen in C++ betrachtet. +// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt +// die Ressourcen akquiriert und der Destruktor diese freigibt. + +// Zum Verständnis, warum dies sinnvoll ist, nachfolgend +// ein einführendes Beispiel: +void doSomethingWithAFile(const char* filename) +{ + // Wir nehmen an, dass nichts schiefgehen wird. + FILE* fh = fopen(filename, "r"); // Öffnen der Datei im read-mode. + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + + fclose(fh); // Schließen des file-handle. +} + +// Unglücklicherweise ist die Fehlerbehandlung äußerst kompliziert. +// Sollte fopen fehlschlagen und "doSomethingWithTheFile" bzw. +// "doSomethingElseWithIt", geben diese einen Fehlercode zurück. +// (Exceptions sind eine bevorzugte Möglichkeit Fehler abzufangen +// , allerdings bei einigen Programmierern, besonders solchen die einen C +// background besitzen, ein unbeliebtes Mittel zur Fehlerbehandlung). +// Nun müssen wir jeden Aufruf auf mögliche auftretende Fehler überprüfen. +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode + if (fh == nullptr) // Der Pointer ist bei einem Fehler NULL . + return false; // Benachrichtigt den Aufrufer über den Fehler. + + // Wir nehmen an, dass jede Funktion false zurückgibt, in einem Fehlerfall + if (!doSomethingWithTheFile(fh)) + { + fclose(fh); // File handle schließen. + return false; // Fehler "melden". + } + + if (!doSomethingElseWithIt(fh)) + { + fclose(fh); // File handle schließen. + return false; // Fehler "melden". + } + + fclose(fh); // File handle schließen. + return true; // Erfolg "melden". +} + +// C-Programmierer handhaben dies häufig durch goto-Anweisungen: +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); + if (fh == nullptr) + return false; + + if (!doSomethingWithTheFile(fh)) + goto failure; + + if (!doSomethingElseWithIt(fh)) + goto failure; + + fclose(fh); // File handle schließen. + return true; // Erfolg "melden". + +failure: + fclose(fh); + return false; // Fehler "melden". +} + +// Insofern Funktionen Fehler durch exceptions indizieren, +// ist dies "sauberer", aber immer noch suboptimal. +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode + if (fh == nullptr) + throw std::runtime_error("Could not open the file."); + + try + { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) + { + // Im Fehlerfall sollte sichergestellt sein, dass die + // Datei geschlossen wird. + fclose(fh); + throw; // Erneutes werfen der Exception + } + + fclose(fh); // Schließen der Datei +} + +// Folgendes ist mit der C++ file stream Klasse (fstream) zu vergleichen. +// fstream verwendet den Destruktor, um die Datei zu schließen. +// Der obige Destruktor wird automatisch aufgerufen, sobald das Objekt +// den Gültigkeitsbereich verlässt. +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream entspricht der Kurzform von "input file stream". + std::ifstream fh(filename); // Öffnen der Datei + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // Die Datei wird automatisch vom Destruktor geschlossen. + +// Diese Vorgehensweise bietet massive Vorteile: +// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst, +// insofern der Destruktor korrekt beschrieben wurde. Es ist möglich +// zu vergessen das Datei-Handle zu schließen, was zu einem "leak" der +// entsprechenden Ressource führt. +// 2. Der Code selbst ist wesentlich "sauberer". +// Der Destruktor wird das Datei-Handle im Hintergrund schließen und der +// Programmierer muss sich darum keinerlei Sorgen machen. +// 3. Der Code ist "exception sicher". +// Egal wo die exception geworfen wird, das Aufäumen wird definitv vollzogen. + +// Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen. +// Weitere Beispiele: +// - Speicher verwenden "unique_ptr" und "shared_ptr". +// - Container - verkettete Listen (linked list), vector (selbst organisierende +// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des +// Gültigkeitsbereichs laufen. +// - Mutex´s verwenden lock_guard und unique_lock. + +///////////////////// +// Container +///////////////////// + +// Die Container der Standard Tenplate Bibliothek beinhaltet einige vordefinierter templates. +// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen +// für den Zugriff und die Maniplulation bereit. + +// Beispielhafte Container: + +// Vector (dynamisches array) +// Erlaubt das Definieren von Arrays oder Listen zur Laufzeit +#include +string val; +vector my_vector; // Initialisierung des Vectors. +cin >> val; +my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu. +my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu (nun zwei Elemente). + +// Für die Iteration über Vektoren stehen zwei Methodiken zu Verfügung: +// Entweder die klassische Iteration über den Index: +for (int i = 0; i < my_vector.size(); i++) +{ + cout << my_vector[i] << endl; // Zugriff auf die Elemente des Vektors über den [] Operator +} + +// Oder die Verwendung von Iteratoren: +vector::iterator it; // Initialisierng des Iterators. +for (it = my_vector.begin(); it != my_vector.end(); ++it) +{ + cout << *it << endl; +} + +// Set (Mengen) +// Sets sind Container, welche einzigartige Elemente beinhalten die einer +// spezifischen Ordnung folgen. + +#include +set ST; // Initialisierung des Sets mit einem Integer Datentyp. +ST.insert(30); // Einfügen des Werts 30 in das Set ST +ST.insert(10); // Einfügen des Werts 10 in das Set ST +ST.insert(20); // Einfügen des Werts 20 in das Set ST +ST.insert(30); // Einfügen des Werts 30 in das Set ST +// Folgende Elemente befinden sich nun in dem Set: +// 10 20 30 + +// Entfernen eines Elements: +ST.erase(20); + +// Set ST: 10 30 +// Für das iterieren verwenden wir Iteratoren: +set::iterator it; + +for(it=ST.begin();it +map mymap; // Initialisierung der Map: char -> Key, int -> Value. + +mymap.insert(pair('A',1)); // Einfügen des Werts "1" für den Key "A". + +mymap.insert(pair('Z',26)); // Einfügen des Werts "26" für den Key "Z". + +// Das Iterieren über Maps: +map::iterator it; +for (it=mymap.begin(); it!=mymap.end(); ++it) + std::cout << it->first << "->" << it->second << '\n'; + +// Ausgabe: +// A->1 +// Z->26 + +// Für das Finden des dazugehörigen Value des Keys. +it = mymap.find('Z'); +cout << it->second; + +// Ausabe: 26 + +// Bemerkung: für "hash maps" sollten die "unordered_map´s" verwendet werden. Diese +// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab +// C++11 verfügbar. + +// Container für nicht-primitve Datentypen benötigen Vergleichsfunktionen im Objekt selbst, +// oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen. +// Allerdings können diese überschrieben werden. +class Foo +{ +public: + int j; + Foo(int a) : j(a) {} +}; + +struct compareFunction +{ + bool operator()(const Foo& a, const Foo& b) const + { + return a.j < b.j; + } +}; + +// Folgender Code ist nicht valide, könnte aber von einigen Compilern +// als valide angesehen werden: +// std::map fooMap; +std::map fooMap; +fooMap[Foo(1)] = 1; +fooMap.find(Foo(1)); // Wahr + + +/////////////////////////////////////// +// Lambda Ausdrücke (C++11 und höher) +/////////////////////////////////////// + +// Lambdas sind eine gängige Methodik um anonyme Funktionen an dem +// Ort der Verwendung zu definieren. Darüber hinaus auch bei der +// Verwendung von Funktionen als Argument einer Funktion. + +// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe +// des zweiten Werts des "pairs" sortiert werden. + +vector > tester; +tester.push_back(make_pair(3, 6)); +tester.push_back(make_pair(1, 9)); +tester.push_back(make_pair(5, 0)); + +// Übergabe des Lambda-Ausdrucks als drittes Argument für die nachfolgende Sortierfunktion. +sort(tester.begin(), tester.end(), [](const pair& lhs, const pair& rhs) +{ + return lhs.second < rhs.second; +}); + +// Beachte den Syntax von Lambda-Ausdrücken. +// Die [] im Lambda Ausdruck werden für die Variablen verwendet. +// Diese so genannte "Capture List" definiert, was außerhalb des Lambdas +// innerhalb der Funktion verfügbar sein soll und in welcher Form. +// Dies kann folgendes sein: +// 1. ein Wert [x] +// 2. eine Referenz [&x] +// 3. eine beliebige Variable, welche sich im Gültigkeitsbereich durch +// die Referenz [&] befindet. +// 4. wie bei 3. aber mithilfe des Werts [=] +// Beispiel: + +vector dog_ids; + +for(int i = 0; i < 3; i++) +{ + dog_ids.push_back(i); +} + +int weight[3] = {30, 50, 10}; + +// Nehmen wir an wir möchten die "dog_ids" gemäß des Gewichts des Hundes sortieren. +// So sollten sich die "dog_ids" wie folgt verhalten: [2, 0, 1] + +// Hier werden Lambdas praktisch: +sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) +{ + return weight[lhs] < weight[rhs]; +}); + + +// Weiterführender Link über Lambda-Ausdrücke: +// http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 + +/////////////////////////////// +// Range For (C++11 und höher) +/////////////////////////////// + +// Range-For Schleifen können verwendet werden, um über Container zu iterieren. +int arr[] = {1, 10, 3}; + +for(int elem: arr) +{ + cout << elem << endl; +} + +// Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden. + +for(auto elem: arr) +{ + // Anweisungen ... +} + +///////////////////// +// Weiteres: +///////////////////// + +// Einige Aspekte von C++ sind für Neueinsteiger häufig überraschend (aber auch für +// C++ Veteranen). +// Der nachfolgende Abschnitt ist leider nicht vollständig: +// C++ ist eine der Sprachen, bei der es ein leichtes ist sich selbst ins Bein zu schießen. + +// Private-Methoden können überschrieben werden +class Foo +{ + virtual void bar(); +}; + +class FooSub : public Foo +{ + virtual void bar(); // Überschreibt Foo::bar! +}; + + +// 0 == false == NULL +bool* pt = new bool; +*pt = 0; // Setzt den Wert des Pointers 'pt' auf false. +pt = 0; // Setzt 'pt' auf den "null-pointer". Keine Compiler-Warnung. + +// nullptr sollte dieses Problem nicht lösen: +int* pt2 = new int; +*pt2 = nullptr; // Kompiliert nicht. +pt2 = nullptr; // Setzt pt2 auf null. + +// Eine Ausnahme bilden bools. +// Dies erlaubt es "null-pointer" zu testen: if(!ptr) +// Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann. +*pt = nullptr; // Kompiliert auch wenn '*pt' ein bool ist! + + +// '=' != '=' != '='! +// Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor +Foo f2; +Foo f1 = f2; + +// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von +// "fooSub". Alle zusätzlichen Member werden verworfen. Diese eigenartige Verhalten +// wird auch "object slicing" genannt. +FooSub fooSub; +Foo f1 = fooSub; + +// Ruft Foo::operator=(Foo&) oder eine andere Variante auf. +Foo f1; +f1 = f2; + +/////////////////////////////////////// +// Tuple (C++11 und höher) +/////////////////////////////////////// + +#include + +// Konzeptionell sind Tuples alten Datenstrukturen sehr ähnlich, allerdings haben diese keine +// benamten Daten-Member, sondern werden durch die Reihenfolge angesprochen. + +// Erstellen des Tuples und das Einfügen eines Werts. +auto first = make_tuple(10, 'A'); +const int maxN = 1e9; +const int maxL = 15; +auto second = make_tuple(maxN, maxL); + +// Ausgabe der Elemente des "first" Tuple. +cout << get<0>(first) << " " << get<1>(first) << "\n"; // Ausgabe : 10 A + +// Ausgabe der Elemente des "second" Tuple. +cout << get<0>(second) << " " << get<1>(second) << "\n"; // Ausgabe: 1000000000 15 + +int first_int; +char first_char; +tie(first_int, first_char) = first; +cout << first_int << " " << first_char << "\n"; // Ausgabe : 10 A + +// Tuple können auch wie folgt erzeugt werden: + +tuple third(11, 'A', 3.14141); +// tuple_size gibt die Anzahl der Elemente in einem Tuple zurück. +// Als "constexpr". + +cout << tuple_size::value << "\n"; // prints: 3 + +// tuple_cat fügt die Elemente eines Tuples aneinander (in der selben Reihenfolge). + +auto concatenated_tuple = tuple_cat(first, second, third); +// concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141) + +cout << get<0>(concatenated_tuple) << "\n"; // Ausgabe: 10 +cout << get<3>(concatenated_tuple) << "\n"; // Ausgabe: 15 +cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A' + + +/////////////////////////////////// +// Logische- und Bitoperatoren +////////////////////////////////// + +// Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen + +// Logische Operatoren. + +// C++ verwendet so genannte "Short-circuit" Evaluierung für boolean-Ausdrücke. +// Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt, +// um den Ausdruck zu bestimmen. + +true && false // Führt **logisches und** aus. +true || false // Führt **logisches oder** aus. +! true // Führt **logisches nicht** aus. + +// Anstelle von Symbolen können auch Schlüsselwörter verwendet werden. +true and false // Führt **logisches und** aus. +true or false // Führt **logisches oder** aus. +not true // Führt **logisches nicht** aus. + +// Bitoperationen + +// **<<** Links-Shift +// **>>** Rechts-Shift + +~4 // Führt bitweises nicht aus. +4 | 3 // Führt bitweises oder aus. +4 & 3 // Führt bitweises und aus. +4 ^ 3 // Führt bitweises xor aus. + +// Gleichwertige Schlüsselwörter: +compl 4 // Führt bitweises nicht aus. +4 bitor 3 // Führt bitweises oder aus. +4 bitand 3 // Führt bitweises und aus. +4 xor 3 // Führt bitweises xor aus. + + +``` +Weiterführende Literatur: + +* Aktuelle Sprachen-Referenz [CPP Reference](http://cppreference.com/w/cpp). +* Zusätzliches: [CPlusPlus](http://cplusplus.com). +* Grundlagen Tutorial: [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb). -- cgit v1.2.3 From 223eff09c3e2444c230dd7fb5d11b66fa79b1c8d Mon Sep 17 00:00:00 2001 From: lchan05 Date: Tue, 28 May 2019 19:09:42 -0400 Subject: added language, resolves #3537 --- de-de/c++-de.html.markdown | 1 + 1 file changed, 1 insertion(+) (limited to 'de-de/c++-de.html.markdown') diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown index 23cc26a8..eec11d61 100644 --- a/de-de/c++-de.html.markdown +++ b/de-de/c++-de.html.markdown @@ -9,6 +9,7 @@ contributors: - ["Ankush Goyal", "http://github.com/ankushg07"] - ["Jatin Dhankhar", "https://github.com/jatindhankhar"] - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"] +lang: de-de --- C++ ist eine Systemprogrammiersprache die, -- cgit v1.2.3 From 41f2b7f168d0599e7567c6a96bec29ac87c68de4 Mon Sep 17 00:00:00 2001 From: LamdaLamdaLamda <25778959+LamdaLamdaLamda@users.noreply.github.com> Date: Sat, 3 Aug 2019 20:18:39 +0200 Subject: [C++/de] fixed wrong spelling (#3579) * Added [C++/de] * [C++/de] filename fixed. * [C++/de] language code in filename added * [C++/de] fixed wrong spelling * [C++/en] smart pointer added --- de-de/c++-de.html.markdown | 208 ++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 106 deletions(-) (limited to 'de-de/c++-de.html.markdown') diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown index eec11d61..cef7514b 100644 --- a/de-de/c++-de.html.markdown +++ b/de-de/c++-de.html.markdown @@ -23,9 +23,11 @@ entworfen wurde um, - generische Programmierung zu unterstützen Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein. -Sie ist weit verbeitet, weil sie in Maschinen-Code compiliert, welches direkt vom Prozessor ausgeführt + +Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welches direkt vom Prozessor ausgeführt werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig -High-Level-Features wie generics, exceptions und Klassen enthält. (wie C) +High-Level-Features wie generics, exceptions und Klassen enthält. + Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der weitverbreitesten Programmiersprachen. @@ -34,19 +36,20 @@ weitverbreitesten Programmiersprachen. // Vergleich zu C ////////////////// -// C++ ist fast eine Untermenge von C and teilt sich grundsätzlich den -// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen. +// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich den +// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen. // Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und -// einen Ineteger als Rückgabetyp besitzt. +// einen Integer als Rückgabetyp besitzt. + // Dieser Wert fungiert als Beendigungsstatus des Programms. // Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen int main(int argc, char** argv) { // Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben - // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style + // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style // strings (char*), welche die Argumente repräsentieren. - // Das erste Argument ist der Name des Programms welches aufgerufen wird. + // Das erste Argument ist der Name des Programms, welches aufgerufen wird. // Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem // die Funktionssignatur "int main()" verwendet wird. @@ -54,12 +57,12 @@ int main(int argc, char** argv) return 0; } -// C++ unterscheidet sich in einigen Punkten: +// C++ unterscheidet sich in einigen Punkten von C: -// In C++ sind Zeichen-Literale chars +// In C++ sind Zeichen-Literale char´s sizeof('c') == sizeof(char) == 1 -// In C sind Zeichen-Literale ints +// In C sind Zeichen-Literale int´s sizeof('c') == sizeof(int) // C++ verwendet striktes prototyping @@ -71,8 +74,8 @@ void func(); // Funktion mit beliebiger Anzahl von Argumenten // Verwende nullptr, anstatt von NULL!!! int* ip = nullptr; -// C standard headers sind in C++ verfügbar. -// C header enden mit .h, während +// C standard header sind in C++ verfügbar. +// C header enden mit .h, während // C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden. // Die C++ Standard Version: @@ -115,10 +118,9 @@ int main() // Argumente können per Standard für eine Funktion gesetzt werden, // wenn diese beim Aufruf nicht bereitgestellt werden. - void doSomethingWithInts(int a = 1, int b = 4) { - // führe Anweisungen mit "ints" aus. + // führe Anweisungen mit "int´s" aus. } int main() @@ -141,18 +143,18 @@ void invalidDeclaration(int a = 1, int b) // Fehler! // Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen, // Funktionen und andere Deklarationen zur Verfügung. // Namespaces können geschachtelt werden. -namespace First +namespace First { - namespace Nested + namespace Nested { void foo() { printf("This is First::Nested::foo\n"); } - } // Ende des Namespaces "Nested" -} // Ende des Namespaces "First" + } // Ende des Namespace "Nested" +} // Ende des Namespace "First" -namespace Second +namespace Second { void foo() { @@ -236,8 +238,8 @@ cout << myString; // "Hello Dog" // C++ besitzt _Referenzen_. // Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können // und nicht Null sein können. -// Sie besitzen den selben Synthax wie Variablen. -// Für die Dereferenzierung ist kein * notwendig und +// Sie besitzen den selben Syntax wie Variablen. +// Für die Dereferenzierung ist kein * notwendig und // & (die Adresse) wird nicht für die Zuweisung verwendet. using namespace std; @@ -261,19 +263,18 @@ cout << fooRef; // Gibt "I am bar" aus // Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo - const string& barRef = bar; // Erzeugt konstante Referenz auf bar. // Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden. barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden. -// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an +// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an, // welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus: string tempObjectFun() { ... } string retVal = tempObjectFun(); // Was passiert nun in der zweiten Zeile: -// - ein String Objekt wird von tempObjectFun zurückgegeben +// - ein String Objekt wird von "tempObjectFun" zurückgegeben // - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt. // - das zurückgegebene Objekt wird zerstört // Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt @@ -285,19 +286,20 @@ foo(bar(tempObjectFun())) // Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben, // wird an bar übergeben und ist zerstört bevor foo aufgerufen wird. -// Zurück zu Referenzen. Die Ausnahme, dass die "am Ende des Ausdrucks" Regel ist gültig, -// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, in welchem Fall das -// Leben auf den aktuellen Gültigkeitsbereich erweitert wird. +// Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist, +// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, ist der Fall, wenn die Lebensdauer +// auf den aktuellen Gültigkeitsbereich erweitert wird. void constReferenceTempObjectFun() { - // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion + // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion const string& constRef = tempObjectFun(); ... } -// Eine andere Art von Referenzen wird in C++11 eingeführt und ist speziell für -// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber -// Vorrechte bei der Auflösung. +// Eine andere Art von Referenzen wurde in C++11 eingeführt und ist speziell für +// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber +// Vorrechte bei der Auflösung zu besitzen. + void someFun(string& s) { ... } // Reguläre Referenz void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt @@ -310,8 +312,8 @@ someFun(tempObjectFun()); // Ruft die Funktion mit der temporären Referenz auf basic_string(const basic_string& other); basic_string(basic_string&& other); -// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später -// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird +// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später +// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird // als "move semantics" bezeichnet (bewegen eines Objekts in ein anderes in C++). ///////////////////// @@ -346,18 +348,18 @@ enum ECarTypes : uint8_t void WriteByteToFile(uint8_t InputValue) { - // Serialisierung von InputValue in eine Datei + // Serialisierung von "InputValue" in eine Datei } void WritePreferredCarTypeToFile(ECarTypes InputCarType) { // Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass - // es sich um ein enum handelt. + // es sich um ein "enum" handelt. WriteByteToFile(InputCarType); } -// Nicht immer ist es gewünscht, dass enums zu einem Integer oder zu einem anderen -// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche +// Nicht immer ist es gewünscht, dass enum´s zu einem Integer oder zu einem anderen +// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche // nicht implizit umgewandelt wird. enum class ECarTypes : uint8_t { @@ -374,8 +376,8 @@ void WriteByteToFile(uint8_t InputValue) void WritePreferredCarTypeToFile(ECarTypes InputCarType) { - // Wird nicht kompilieren, da ECarTypes ein "uint8_t" ist, da das enum - // als "enum class" deklariert wurde! + // Wird nicht kompilieren, da "ECarTypes" ein "uint8_t" ist, da das enum + // als "enum class" deklariert wurde! WriteByteToFile(InputCarType); } @@ -401,15 +403,15 @@ public: // Standard Konstruktor Dog(); - // Member-Funktonensdeklaration (Implementierung folgt) + // Member-Funktionsdeklaration (Implementierung folgt). // Bemerkung: std::string statt der Verwendung von namespace std; // "using namespace" sollte niemals in einem header verwendet werden. void setName(const std::string& dogsName); void setWeight(int dogsWeight); - // Funktionen, die Objekte nicht ändern sollte mit const deklariert werden. - // Funktionen müssen explizit als "virtual" deklariert werden, um in einer + // Funktionen, die Objekte nicht ändern, sollten mit const deklariert werden. + // Funktionen müssen explizit als "virtual" deklariert werden, um in einer // abgeleiteten Klassen überschrieben zu werden. // Aus performance Gründen sind Funktionen nicht per default virtual. virtual void print() const; @@ -419,24 +421,24 @@ public: void bark() const { std::cout << name << " barks!\n"; } // Neben Konstruktoren, bietet C++ Destruktoren. - // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder - // seinen Wertebereich verlässt. + // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder + // seinen Wertebereich verlässt. // Dies ermöglicht mächtige Paradigmen, wie auch RAII. // Destruktoren sollten virtual sein, wenn eine Klasse von ihr // abgeleitet wird. Ist dieser nicht virtual, dann wird der - // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern + // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern // das Objekt durch eine Referenz/Pointer der Basisklasse entfernt wird. virtual ~Dog(); }; // Ein Semikolon schließt die Definition der Klasse ab. -// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implmentiert. +// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implementiert. Dog::Dog() { std::cout << "A dog has been constructed\n"; } -// Objekte sollten als Referenz übergeben werden und wenn diese nicht +// Objekte sollten als Referenz übergeben werden und wenn diese nicht // verändert werden sollen, sollte das Objekt als const Referenz übergeben werden. void Dog::setName(const std::string& dogsName) { @@ -468,8 +470,6 @@ int main() return 0; } // Ausgabe: "Goodbye Barkley" -// Vererbung: - // Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse // und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese // nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter. @@ -481,7 +481,7 @@ public: // Überschreibt das Verhalten der "print" Funktion für alle "OwnedDogs". // Siehe: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping // für eine grundlegende Einführung in "Subtype Polymorphismus". - // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die + // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die // Methode der Basisklasse tatsächlich überschrieben wurde. void print() const override; @@ -555,7 +555,7 @@ Point& Point::operator+=(const Point& rhs) return *this; } -int main () +int main () { Point up (0,1); Point right (1,0); @@ -574,23 +574,23 @@ int main () // Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren. // Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können // sie für funktionale Klassen verwendet werden. -// Tatsächlich bilden templates die Turing-Vollständigkeit +// Tatsächlich bilden templates die Turing-Vollständigkeit // (universelle Programmierbarkeit) ab. // Zu Beginn ein einführendes Beispiel der generischen Programmierung. // Die Definition einer Klasse bzw. Funktion, welche mit dem Typ T parametriert wird. template -class Box +class Box { public: // T repräsentiert an dieser Stelle einen beliebigen Typen. void insert(const T&) { ... } }; -// Während der Kompilierung generiert der Kompiler Kopien für jedes Template, wobei -// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte -// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template +// Während der Kompilierung generiert der Compiler Kopien für jedes template, wobei +// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte +// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template // komplett im header definiert. // Erzeugung einer Template-Klasse auf dem stack: @@ -609,7 +609,7 @@ boxOfBox.insert(intBox); // Manchmal ist folgende Notation anzutreffen: // template // Das 'class' Schlüsselwort und das 'typename' Schlüsselwort -// sind fast identisch hinsichtlich der Funktionalität. Weitere +// sind fast identisch hinsichtlich der Funktionalität. Weitere // Informationen auf: http://en.wikipedia.org/wiki/Typename // Eine template-Funktion: @@ -623,7 +623,7 @@ void barkThreeTimes(const T& input) // Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters // definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen -// prüfen. Somit funktioniert die zuvor definiert Funktion für jeden Typ 'T', die die +// prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die // const Methode 'bark' implementiert hat. Dog fluffy; @@ -632,14 +632,14 @@ barkThreeTimes(fluffy); // Gibt "Fluffy barks" dreimal aus. // Template Parameter müssen keine Klassen sein. template -void printMessage() +void printMessage() { cout << "Learn C++ in " << Y << " minutes!" << endl; } // Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden. // Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht -// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die +// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die // Funktion oder Klasse als template deklariert werden. template<> void printMessage<10>() @@ -655,17 +655,17 @@ printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus. // Ausnahme Behandlungen (Exception-Handling) ///////////////////// -// Die Standard Bibliothek bietet einige Exceptions. +// Die Standard Bibliothek bietet einige exceptions. // Siehe: http://en.cppreference.com/w/cpp/error/exception. -// Grundsätzlich können alle Typen als Exception geworfen werden. +// Grundsätzlich können alle Typen als exception geworfen werden. #include #include -// Alle Exceptions, die in dem "try" Block geworfen werden, können mittels +// Alle exceptions, die in dem "try" Block geworfen werden, können mittels // "catch" abgefangen werden. -try +try { - // Exceptions sollten nicht auf dem heap mithilfe + // exceptions sollten nicht auf dem heap mithilfe // von "new" allokiert werden. throw std::runtime_error("A problem occurred"); } @@ -690,7 +690,7 @@ catch (...) // RAII steht für "Resource Acquisition Is Initialization". // Oft wird dies als eines der wichtigsten Paradigmen in C++ betrachtet. -// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt +// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt // die Ressourcen akquiriert und der Destruktor diese freigibt. // Zum Verständnis, warum dies sinnvoll ist, nachfolgend @@ -726,7 +726,7 @@ bool doSomethingWithAFile(const char* filename) return false; // Fehler "melden". } - if (!doSomethingElseWithIt(fh)) + if (!doSomethingElseWithIt(fh)) { fclose(fh); // File handle schließen. return false; // Fehler "melden". @@ -770,12 +770,12 @@ void doSomethingWithAFile(const char* filename) doSomethingWithTheFile(fh); doSomethingElseWithIt(fh); } - catch (...) + catch (...) { - // Im Fehlerfall sollte sichergestellt sein, dass die + // Im Fehlerfall sollte sichergestellt sein, dass die // Datei geschlossen wird. - fclose(fh); - throw; // Erneutes werfen der Exception + fclose(fh); + throw; // Erneutes werfen der exception } fclose(fh); // Schließen der Datei @@ -796,7 +796,7 @@ void doSomethingWithAFile(const std::string& filename) } // Die Datei wird automatisch vom Destruktor geschlossen. // Diese Vorgehensweise bietet massive Vorteile: -// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst, +// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst, // insofern der Destruktor korrekt beschrieben wurde. Es ist möglich // zu vergessen das Datei-Handle zu schließen, was zu einem "leak" der // entsprechenden Ressource führt. @@ -804,13 +804,13 @@ void doSomethingWithAFile(const std::string& filename) // Der Destruktor wird das Datei-Handle im Hintergrund schließen und der // Programmierer muss sich darum keinerlei Sorgen machen. // 3. Der Code ist "exception sicher". -// Egal wo die exception geworfen wird, das Aufäumen wird definitv vollzogen. +// Egal wo die exception geworfen wird, das Aufräumen wird definitiv vollzogen. // Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen. // Weitere Beispiele: // - Speicher verwenden "unique_ptr" und "shared_ptr". // - Container - verkettete Listen (linked list), vector (selbst organisierende -// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des +// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des // Gültigkeitsbereichs laufen. // - Mutex´s verwenden lock_guard und unique_lock. @@ -818,7 +818,7 @@ void doSomethingWithAFile(const std::string& filename) // Container ///////////////////// -// Die Container der Standard Tenplate Bibliothek beinhaltet einige vordefinierter templates. +// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter templates. // Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen // für den Zugriff und die Maniplulation bereit. @@ -842,7 +842,7 @@ for (int i = 0; i < my_vector.size(); i++) // Oder die Verwendung von Iteratoren: vector::iterator it; // Initialisierng des Iterators. -for (it = my_vector.begin(); it != my_vector.end(); ++it) +for (it = my_vector.begin(); it != my_vector.end(); ++it) { cout << *it << endl; } @@ -861,13 +861,13 @@ ST.insert(30); // Einfügen des Werts 30 in das Set ST // 10 20 30 // Entfernen eines Elements: -ST.erase(20); +ST.erase(20); // Set ST: 10 30 // Für das iterieren verwenden wir Iteratoren: set::iterator it; -for(it=ST.begin();it('A',1)); // Einfügen des Werts "1" für den Key "A" mymap.insert(pair('Z',26)); // Einfügen des Werts "26" für den Key "Z". -// Das Iterieren über Maps: +// Das Iterieren über Maps: map::iterator it; for (it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << "->" << it->second << '\n'; @@ -918,25 +918,25 @@ cout << it->second; // sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab // C++11 verfügbar. -// Container für nicht-primitve Datentypen benötigen Vergleichsfunktionen im Objekt selbst, +// Container für nicht-primitive Datentypen benötigen Vergleichsfunktionen im Objekt selbst, // oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen. // Allerdings können diese überschrieben werden. -class Foo +class Foo { public: int j; Foo(int a) : j(a) {} }; -struct compareFunction +struct compareFunction { - bool operator()(const Foo& a, const Foo& b) const + bool operator()(const Foo& a, const Foo& b) const { return a.j < b.j; } }; -// Folgender Code ist nicht valide, könnte aber von einigen Compilern +// Folgender Code ist nicht valide, könnte aber von einigen Compilern // als valide angesehen werden: // std::map fooMap; std::map fooMap; @@ -949,10 +949,10 @@ fooMap.find(Foo(1)); // Wahr /////////////////////////////////////// // Lambdas sind eine gängige Methodik um anonyme Funktionen an dem -// Ort der Verwendung zu definieren. Darüber hinaus auch bei der +// Ort der Verwendung zu definieren. Darüber hinaus auch bei der // Verwendung von Funktionen als Argument einer Funktion. -// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe +// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe // des zweiten Werts des "pairs" sortiert werden. vector > tester; @@ -968,19 +968,19 @@ sort(tester.begin(), tester.end(), [](const pair& lhs, const pair dog_ids; -for(int i = 0; i < 3; i++) +for(int i = 0; i < 3; i++) { dog_ids.push_back(i); } @@ -1013,8 +1013,7 @@ for(int elem: arr) } // Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden. - -for(auto elem: arr) +for(auto elem: arr) { // Anweisungen ... } @@ -1029,18 +1028,17 @@ for(auto elem: arr) // C++ ist eine der Sprachen, bei der es ein leichtes ist sich selbst ins Bein zu schießen. // Private-Methoden können überschrieben werden -class Foo +class Foo { virtual void bar(); }; -class FooSub : public Foo +class FooSub : public Foo { virtual void bar(); // Überschreibt Foo::bar! }; - -// 0 == false == NULL +// 0 == false == NULL bool* pt = new bool; *pt = 0; // Setzt den Wert des Pointers 'pt' auf false. pt = 0; // Setzt 'pt' auf den "null-pointer". Keine Compiler-Warnung. @@ -1050,18 +1048,17 @@ int* pt2 = new int; *pt2 = nullptr; // Kompiliert nicht. pt2 = nullptr; // Setzt pt2 auf null. -// Eine Ausnahme bilden bools. +// Eine Ausnahme bilden bool´s. // Dies erlaubt es "null-pointer" zu testen: if(!ptr) // Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann. -*pt = nullptr; // Kompiliert auch wenn '*pt' ein bool ist! - +*pt = nullptr; // Kompiliert auch, wenn '*pt' ein bool ist! // '=' != '=' != '='! // Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor Foo f2; Foo f1 = f2; -// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von +// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von // "fooSub". Alle zusätzlichen Member werden verworfen. Diese eigenartige Verhalten // wird auch "object slicing" genannt. FooSub fooSub; @@ -1077,10 +1074,10 @@ f1 = f2; #include -// Konzeptionell sind Tuples alten Datenstrukturen sehr ähnlich, allerdings haben diese keine -// benamten Daten-Member, sondern werden durch die Reihenfolge angesprochen. +// Konzeptionell sind Tuple´s alten Datenstrukturen sehr ähnlich, allerdings haben diese keine +// bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen. -// Erstellen des Tuples und das Einfügen eines Werts. +// Erstellen des Tuples und das Einfügen eines Werts. auto first = make_tuple(10, 'A'); const int maxN = 1e9; const int maxL = 15; @@ -1122,8 +1119,7 @@ cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A' // Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen // Logische Operatoren. - -// C++ verwendet so genannte "Short-circuit" Evaluierung für boolean-Ausdrücke. +// C++ verwendet so genannte "Short-circuit" Evaluierung für Boolean-Ausdrücke. // Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt, // um den Ausdruck zu bestimmen. -- cgit v1.2.3 From bcb704c96063c26b7ba1fb6ea3f767a0c22b7b31 Mon Sep 17 00:00:00 2001 From: Marco Camenzind Date: Tue, 12 Nov 2019 09:37:33 +0100 Subject: Fixed some typos in german translation for C++ --- de-de/c++-de.html.markdown | 49 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'de-de/c++-de.html.markdown') diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown index cef7514b..48c245d8 100644 --- a/de-de/c++-de.html.markdown +++ b/de-de/c++-de.html.markdown @@ -9,6 +9,7 @@ contributors: - ["Ankush Goyal", "http://github.com/ankushg07"] - ["Jatin Dhankhar", "https://github.com/jatindhankhar"] - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"] + - ["caminsha", "https://github.com/caminsha"] lang: de-de --- @@ -22,9 +23,9 @@ entworfen wurde um, - Objektorientierung zu unterstützen - generische Programmierung zu unterstützen -Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein. +Durch seine Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein. -Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welches direkt vom Prozessor ausgeführt +Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welcher direkt vom Prozessor ausgeführt werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig High-Level-Features wie generics, exceptions und Klassen enthält. @@ -36,7 +37,7 @@ weitverbreitesten Programmiersprachen. // Vergleich zu C ////////////////// -// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich den +// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich die // Syntax für Variablen Deklarationen, primitiven Typen und Funktionen. // Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und @@ -137,7 +138,7 @@ void invalidDeclaration(int a = 1, int b) // Fehler! ///////////// -// Namespaces (Namesräume) +// Namespaces (Namensräume) ///////////// // Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen, @@ -169,7 +170,7 @@ void foo() int main() { - // Fügt all Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope). + // Fügt alle Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope). // "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus // dem namespace foo oder darüberliegenden aufgerufen wird. using namespace Second; @@ -283,7 +284,7 @@ string retVal = tempObjectFun(); // für Details). Wie in diesem Code: foo(bar(tempObjectFun())) -// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben, +// Nehmen wir an, foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben, // wird an bar übergeben und ist zerstört bevor foo aufgerufen wird. // Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist, @@ -335,7 +336,7 @@ ECarTypes GetPreferredCarType() return ECarTypes::Hatchback; } -// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zu zuweisen. Dies +// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zuzuweisen. Dies // kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung // zwischen Typen bzw. Konstanten. enum ECarTypes : uint8_t @@ -574,7 +575,7 @@ int main () // Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren. // Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können // sie für funktionale Klassen verwendet werden. -// Tatsächlich bilden templates die Turing-Vollständigkeit +// Tatsächlich bilden Templates die Turing-Vollständigkeit // (universelle Programmierbarkeit) ab. @@ -588,12 +589,12 @@ public: void insert(const T&) { ... } }; -// Während der Kompilierung generiert der Compiler Kopien für jedes template, wobei +// Während der Kompilierung generiert der Compiler Kopien für jedes Template, wobei // hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte // Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template // komplett im header definiert. -// Erzeugung einer Template-Klasse auf dem stack: +// Erzeugung einer Template-Klasse auf dem Stack: Box intBox; // eine der zu erwartenden Verwendungen: @@ -612,7 +613,7 @@ boxOfBox.insert(intBox); // sind fast identisch hinsichtlich der Funktionalität. Weitere // Informationen auf: http://en.wikipedia.org/wiki/Typename -// Eine template-Funktion: +// Eine Template-Funktion: template void barkThreeTimes(const T& input) { @@ -622,7 +623,7 @@ void barkThreeTimes(const T& input) } // Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters -// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen +// definiert wurde. Der Compiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen // prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die // const Methode 'bark' implementiert hat. @@ -637,10 +638,10 @@ void printMessage() cout << "Learn C++ in " << Y << " minutes!" << endl; } -// Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden. -// Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht +// Des Weiteren können Templates aus Effizienzgründen genauer spezifiziert werden. +// Selbstverständlich sind reale Probleme, welche genauer spezifiziert werden, nicht // derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die -// Funktion oder Klasse als template deklariert werden. +// Funktion oder Klasse als Template deklariert werden. template<> void printMessage<10>() { @@ -818,7 +819,7 @@ void doSomethingWithAFile(const std::string& filename) // Container ///////////////////// -// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter templates. +// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter Templates. // Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen // für den Zugriff und die Maniplulation bereit. @@ -876,7 +877,7 @@ for(it=ST.begin();it > tester; @@ -966,7 +967,7 @@ sort(tester.begin(), tester.end(), [](const pair& lhs, const pair -// Konzeptionell sind Tuple´s alten Datenstrukturen sehr ähnlich, allerdings haben diese keine +// Konzeptionell sind Tupel alten Datenstrukturen sehr ähnlich, allerdings haben diese keine // bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen. -// Erstellen des Tuples und das Einfügen eines Werts. +// Erstellen des Tupels und das Einfügen eines Werts. auto first = make_tuple(10, 'A'); const int maxN = 1e9; const int maxL = 15; @@ -1102,7 +1103,7 @@ tuple third(11, 'A', 3.14141); cout << tuple_size::value << "\n"; // prints: 3 -// tuple_cat fügt die Elemente eines Tuples aneinander (in der selben Reihenfolge). +// tuple_cat fügt die Elemente eines Tupels aneinander (in der selben Reihenfolge). auto concatenated_tuple = tuple_cat(first, second, third); // concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141) -- cgit v1.2.3 From aa35898ad7df7294347611dde302ea046bff434c Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 16 Nov 2019 22:10:37 +0100 Subject: Changed two typos I did not see before review --- de-de/c++-de.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'de-de/c++-de.html.markdown') diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown index 48c245d8..87e75ad6 100644 --- a/de-de/c++-de.html.markdown +++ b/de-de/c++-de.html.markdown @@ -819,9 +819,9 @@ void doSomethingWithAFile(const std::string& filename) // Container ///////////////////// -// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter Templates. +// Die Container der Standard template Bibliothek beinhaltet einige vordefinierte Templates. // Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen -// für den Zugriff und die Maniplulation bereit. +// für den Zugriff und die Manipulation bereit. // Beispielhafte Container: -- cgit v1.2.3