From 32ae4b8fae31683cce5b794b401066434281ba86 Mon Sep 17 00:00:00 2001 From: b0rbor4d Date: Wed, 15 Apr 2026 00:25:52 +0200 Subject: [PATCH] Add Modul 8 C++: STL, Iteratoren, Lambdas --- src/cpp_examples/module8_stl_cpp.cpp | 333 +++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 src/cpp_examples/module8_stl_cpp.cpp diff --git a/src/cpp_examples/module8_stl_cpp.cpp b/src/cpp_examples/module8_stl_cpp.cpp new file mode 100644 index 0000000..4b6807e --- /dev/null +++ b/src/cpp_examples/module8_stl_cpp.cpp @@ -0,0 +1,333 @@ +// ============================================ +// C++ Vergleich: Modul 8 - STL Fortgeschritten +// Iteratoren, Funktoren, Lambdas, Algorithmen +// ============================================ + +#include +#include +#include +#include +#include +#include +#include +#include + +// ============================================ +// 1. ITERATOREN +// ============================================ +void demo_iterators() { + std::cout << "=== C++: Iteratoren ===\n\n"; + + std::vector vec = {10, 20, 30, 40, 50}; + + // Iterator-Typen + std::cout << "1. Verschiedene Iterator-Typen:\n"; + + // begin() / end() - normale Iteratoren + std::cout << " Forward: "; + for (auto it = vec.begin(); it != vec.end(); ++it) { + std::cout << *it << " "; + } + std::cout << "\n"; + + // rbegin() / rend() - reverse Iteratoren + std::cout << " Reverse: "; + for (auto it = vec.rbegin(); it != vec.rend(); ++it) { + std::cout << *it << " "; + } + std::cout << "\n"; + + // const_iterator (nur lesen) + std::cout << " Const: "; + for (std::vector::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) { + // *it = 100; // ERROR: Read-only! + std::cout << *it << " "; + } + std::cout << "\n\n"; + + // Iterator-Arithmetik (nur RandomAccess-Iteratoren) + std::cout << "2. Iterator-Arithmetik:\n"; + auto it = vec.begin(); + std::cout << " *it = " << *it << "\n"; + std::cout << " *(it+2) = " << *(it + 2) << "\n"; + std::cout << " *(end-1) = " << *(vec.end() - 1) << "\n\n"; +} + +// ============================================ +// 2. FUNKTOREN (Function Objects) +// ============================================ + +// Eigener Funktor +class GreaterThan { +private: + int threshold_; + +public: + explicit GreaterThan(int threshold) : threshold_(threshold) {} + + // operator() überladen + bool operator()(int value) const { + return value > threshold_; + } +}; + +// Funktor mit Zustand +class AverageCalculator { +private: + double sum_ = 0; + int count_ = 0; + +public: + void operator()(int value) { + sum_ += value; + count_++; + } + + double average() const { + return count_ > 0 ? sum_ / count_ : 0; + } +}; + +void demo_functors() { + std::cout << "=== C++: Funktoren ===\n\n"; + + std::vector vec = {10, 25, 5, 30, 15, 40}; + + // 1. Eigener Funktor + std::cout << "1. GreaterThan Funktor:\n"; + GreaterThan gt20(20); + + auto it = std::find_if(vec.begin(), vec.end(), gt20); + if (it != vec.end()) { + std::cout << " Erster Wert > 20: " << *it << "\n"; + } + + // Zählen + int count = std::count_if(vec.begin(), vec.end(), GreaterThan(15)); + std::cout << " Werte > 15: " << count << "\n\n"; + + // 2. Funktor mit Zustand + std::cout << "2. AverageCalculator (Zustand):\n"; + AverageCalculator avg; + for (int x : vec) { + avg(x); // Aufruf wie Funktion + } + std::cout << " Durchschnitt: " << avg.average() << "\n\n"; +} + +// ============================================ +// 3. LAMBDAS (C++11) +// ============================================ +void demo_lambdas() { + std::cout << "=== C++: Lambdas ===\n\n"; + + std::vector vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + // Lambda-Syntax: [capture](params) -> return_type { body } + + // 1. Einfaches Lambda + std::cout << "1. Einfaches Lambda:\n"; + auto square = [](int x) { return x * x; }; + std::cout << " square(5) = " << square(5) << "\n\n"; + + // 2. Lambda in Algorithmus + std::cout << "2. Lambda in std::for_each:\n"; + std::for_each(vec.begin(), vec.end(), [](int x) { + std::cout << x * x << " "; + }); + std::cout << "\n\n"; + + // 3. Lambda mit Capture + std::cout << "3. Capture (Werte einfangen):\n"; + int factor = 3; + auto multiply = [factor](int x) { return x * factor; }; + std::cout << " 5 * " << factor << " = " << multiply(5) << "\n\n"; + + // 4. Mutable Lambda (veränderbarer Capture) + std::cout << "4. Mutable Lambda:\n"; + int counter = 0; + auto increment = [counter]() mutable { return ++counter; }; + std::cout << " " << increment() << " " << increment() << " " << increment() << "\n"; + std::cout << " Original counter: " << counter << " (unverändert!)\n\n"; + + // 5. Capture by reference + std::cout << "5. Capture by Reference:\n"; + int sum = 0; + std::for_each(vec.begin(), vec.end(), [&sum](int x) { + sum += x; + }); + std::cout << " Summe: " << sum << "\n\n"; + + // 6. Generic Lambda (C++14) + std::cout << "6. Generic Lambda (auto Parameter):\n"; + auto generic = [](auto x, auto y) { return x + y; }; + std::cout << " int: " << generic(3, 4) << "\n"; + std::cout << " double: " << generic(3.5, 2.5) << "\n"; + std::cout << " string: " << generic(std::string("Hello"), std::string(" World")) << "\n\n"; +} + +// ============================================ +// 4. STL-ALGORITHMEN +// ============================================ +void demo_algorithms() { + std::cout << "=== C++: STL Algorithmen ===\n\n"; + + std::vector vec = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; + + // 1. Sorting + std::cout << "1. Sorting:\n"; + std::sort(vec.begin(), vec.end()); + std::cout << " Sortiert: "; + for (int x : vec) std::cout << x << " "; + std::cout << "\n"; + + // Reverse sort with lambda + std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; }); + std::cout << " Absteigend: "; + for (int x : vec) std::cout << x << " "; + std::cout << "\n\n"; + + // 2. Searching + std::cout << "2. Searching:\n"; + if (std::binary_search(vec.begin(), vec.end(), 5)) { + std::cout << " 5 gefunden!\n"; + } + + auto [min_it, max_it] = std::minmax_element(vec.begin(), vec.end()); + std::cout << " Min: " << *min_it << ", Max: " << *max_it << "\n\n"; + + // 3. Transform (map) + std::cout << "3. Transform:\n"; + std::vector doubled; + std::transform(vec.begin(), vec.end(), std::back_inserter(doubled), + [](int x) { return x * 2; }); + std::cout << " Verdoppelt: "; + for (int x : doubled) std::cout << x << " "; + std::cout << "\n\n"; + + // 4. Filter (copy_if) + std::cout << "4. Filter (copy_if):\n"; + std::vector even; + std::copy_if(vec.begin(), vec.end(), std::back_inserter(even), + [](int x) { return x % 2 == 0; }); + std::cout << " Gerade Zahlen: "; + for (int x : even) std::cout << x << " "; + std::cout << "\n\n"; + + // 5. Reduce (accumulate) + std::cout << "5. Accumulate:\n"; + int sum = std::accumulate(vec.begin(), vec.end(), 0); + int product = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies()); + std::cout << " Summe: " << sum << "\n"; + std::cout << " Produkt: " << product << "\n\n"; +} + +// ============================================ +// 5. RANGE-BASED FOR LOOP +// ============================================ +void demo_range_based_for() { + std::cout << "=== C++: Range-based for loop ===\n\n"; + + std::vector names = {"Alice", "Bob", "Charlie"}; + std::map scores = {{"Alice", 95}, {"Bob", 87}, {"Charlie", 92}}; + + // By value (Kopie) + std::cout << "1. By Value (Kopie):\n "; + for (std::string name : names) { + name += "!"; // Ändert nur Kopie + std::cout << name << " "; + } + std::cout << "\n Original: "; + for (const auto& name : names) std::cout << name << " "; + std::cout << "\n\n"; + + // By reference (Original ändern) + std::cout << "2. By Reference:\n "; + for (auto& name : names) { + name[0] = std::tolower(name[0]); // Ändert Original! + std::cout << name << " "; + } + std::cout << "\n\n"; + + // Const reference (nur lesen, effizient) + std::cout << "3. Const Reference:\n "; + for (const auto& [name, score] : scores) { + std::cout << name << ": " << score << " "; + } + std::cout << "\n\n"; +} + +// ============================================ +// 6. FUNKTIONALE KOMPOSITION +// ============================================ +void demo_functional() { + std::cout << "=== C++: Funktionale Komposition ===\n\n"; + + // std::function für flexiblen Funktions-Typ + std::function operations; + + // Compose: f(g(x)) + auto add10 = [](int x) { return x + 10; }; + auto mul2 = [](int x) { return x * 2; }; + + // compose: add10(mul2(x)) + auto compose = [add10, mul2](int x) { + return add10(mul2(x)); + }; + + std::cout << "1. Komposition: add10(mul2(5)) = " << compose(5) << "\n"; + // 5 * 2 = 10, 10 + 10 = 20 + + // Pipeline-ähnliche Verarbeitung + std::vector data = {1, 2, 3, 4, 5}; + + auto result = data + | std::views::transform([](int x) { return x * 2; }) + | std::views::filter([](int x) { return x > 4; }) + | std::views::take(3); + + // C++23 Ranges (falls verfügbar) + // Oder klassisch: + std::vector pipeline_result; + for (int x : data) { + int doubled = x * 2; + if (doubled > 4) { + pipeline_result.push_back(doubled); + } + } + + std::cout << "2. Pipeline Ergebnis: "; + for (int x : pipeline_result) std::cout << x << " "; + std::cout << "\n\n"; +} + +// ============================================ +// HAUPTPROGRAMM +// ============================================ +int main() { + std::cout << "=== C++ STL: Iteratoren, Lambdas, Algorithmen ===\n\n"; + + demo_iterators(); + demo_functors(); + demo_lambdas(); + demo_algorithms(); + demo_range_based_for(); + demo_functional(); + + std::cout << "=== Vergleich: C vs C++ ===\n\n"; + std::cout << "C:\n"; + std::cout << " - Manuelle Iteration (i = 0; i < n; i++)\n"; + std::cout << " - Function Pointers für Callbacks\n"; + std::cout << " - Keine generische Sortierung\n"; + std::cout << " - Manuelle Algorithmen-Implementierung\n\n"; + + std::cout << "C++:\n"; + std::cout << " - Iteratoren (einheitlich für alle Container)\n"; + std::cout << " - Funktoren + Lambdas (typsicher, inline-fähig)\n"; + std::cout << " - 100+ generische Algorithmen\n"; + std::cout << " - Range-based for (elegant)\n"; + std::cout << " - std::function für flexible Callbacks\n"; + std::cout << " - Algorithmen sind optimiert und getestet\n"; + + return 0; +}