Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fundamentos de Programacion con C++ : Casos pra...

Fundamentos de Programacion con C++ : Casos practicos para ingenierıa y ciencias (Parte1)

Avatar for Abraham Zamudio

Abraham Zamudio

October 02, 2026

More Decks by Abraham Zamudio

Other Decks in Education

Transcript

  1. Casos prácticos para ingenierı́a y ciencias Abraham Zamudio Chauca 2026

    Aprendemos Juntos Fundamentos de Programación con C++
  2. ¿Qué es C++? Un lenguaje de propósito general C++ combina

    la abstracción de alto nivel con el control directo del hardware: evoluciona desde C añadiendo clases, objetos y programación genérica. Un solo lenguaje que soporta estilos procedural, orientado a objetos y genérico. Estándar de la industria en sistemas operativos, motores de videojuegos, software financiero y bibliotecas de alto rendimiento. • • Rendimiento Portabilidad • Control Fundamentos de Programación con C++ Abraham Zamudio Chauca 2 / 17
  3. • Creado por Bjarne Stroustrup en la década Origen y

    estándares de 1980 como “C con clases”. • Estandarizado por ISO: ◦ C++98 ◦ C++11 ◦ C++14 ◦ C++17 ◦ C++20 ◦ C++23 Bjarne Stroustrup, creador de C++ (década de 1980). • Los estándares modernos mejoran seguridad, expresividad y rendimiento. • Compiladores comunes: GCC, Clang y MSVC. Fundamentos de Programación con C++ GCC, uno de los compiladores más usados de C++. Abraham Zamudio Chauca 3 / 17
  4. C++98: el primer estándar • Primer estándar ISO de C++;

    consolida la base del lenguaje. • Soporte de programación orientada a objetos: clases, herencia y polimorfismo. • Biblioteca estándar: iostream, STL, contenedores, algoritmos e iteradores. • Manejo de excepciones y RTTI. • Espacios de nombres, plantillas y programación genérica. Fundamentos de Programación con C++ Abraham Zamudio Chauca 4 / 17
  5. C++98: ası́ se escribı́a // ejemplo_cpp98.cpp // Compilar con: g++

    -std=c++98 -pedantic -Wall ejemplo_cpp98.cpp -o ejemplo_cpp98 #include <iostream> #include <string> #include <vector> #include <algorithm> #include <sstream> class Producto { public: Producto(const std::string& nombre, double precio) : nombre_(nombre), precio_(precio) {} const std::string& nombre() const { return nombre_; } double precio() const { return precio_; } std::string descripcion() const { std::ostringstream os; // sin std::to_string: conversión a mano os << nombre_ << " ($" << precio_ << ")"; return os.str(); } private: std::string nombre_; double precio_; }; // Sin lambdas: los algoritmos exigı́an funtores (objetos función) struct MayorPrecio { bool operator()(const Producto& a, const Producto& b) const { return a.precio() > b.precio(); } }; int main() { // Sin initializer lists: elemento a elemento con push_back std::vector<Producto> catalogo; catalogo.push_back(Producto("Teclado", 25.50)); catalogo.push_back(Producto("Monitor", 120.00)); catalogo.push_back(Producto("Raton", 12.75)); // Ordenar con funtor en lugar de lambda std::sort(catalogo.begin(), catalogo.end(), MayorPrecio()); // Sin range-for ni auto: iterador explı́cito y verboso for (std::vector<Producto>::iterator it = catalogo.begin(); it != catalogo.end(); ++it) { std::cout << it->descripcion() << std::endl; } // Memoria manual: new/delete (unique_ptr/make_unique no existı́an) Producto* destacado = new Producto("Portatil", 899.99); std::cout << "Destacado: " << destacado->descripcion() << std::endl; delete destacado; return 0; } Fundamentos de Programación con C++ Abraham Zamudio Chauca 5 / 17
  6. C++11: modernización del lenguaje • auto, nullptr y override mejoran

    claridad y seguridad. • Expresiones lambda, std::function y programación más funcional. • Semántica de movimiento y punteros inteligentes: std::unique ptr y std::shared ptr. • Concurrencia estándar: std::thread, std::mutex y std::atomic. • constexpr, enum class, listas de inicialización y plantillas variádicas. Fundamentos de Programación con C++ Abraham Zamudio Chauca 6 / 17
  7. C++11: ası́ se modernizó #include <iostream> #include <vector> #include <memory>

    #include <thread> #include <mutex> #include <chrono> int main() { // 4. Listas de inicializacion std::vector<int> ids = {101, 102, 103, 104}; // 5. Smart pointers y Move semantics std::vector<std::unique_ptr<Tarea>> tareas; for (int id : ids) { tareas.push_back( std::unique_ptr<Tarea>(new TareaDatos(id))); } // 1. enum class: Fuertemente tipado enum class Estado { Pendiente, Procesando, Completado }; // 6. Concurrencia (thread, mutex) std::mutex mtx; std::vector<std::thread> hilos; // 2. constexpr: Constante en compilacion constexpr int MAX_HILOS = 4; class Tarea { public: virtual ˜Tarea() = default; // 3. override: verificacion del compilador virtual void ejecutar() = 0; }; // 7. Lambda (Programacion funcional) auto procesar_lote = [&](int inicio, int fin) { for (int i = inicio; i < fin; ++i) { tareas[i]->ejecutar(); std::lock_guard<std::mutex> lock(mtx); std::cout << "Hilo terminado.\n"; } }; class TareaDatos : public Tarea { int id_; Estado estado_; public: TareaDatos(int id) : id_(id), estado_(Estado::Pendiente) {} // Lanzamos 2 hilos usando la lambda hilos.emplace_back(procesar_lote, 0, 2); hilos.emplace_back(procesar_lote, 2, 4); // 8. Range-based for loop y auto for (auto& h : hilos) { if (h.joinable()) h.join(); } void ejecutar() override { estado_ = Estado::Procesando; std::this_thread::sleep_for( std::chrono::milliseconds(50)); estado_ = Estado::Completado; std::cout << "Tarea " << id_ << " completada.\n"; } // 9. nullptr: Puntero nulo seguro Tarea* ptr_crudo = nullptr; if (ptr_crudo == nullptr) { std::cout << "Puntero nulo seguro.\n"; } return 0; }; } Fundamentos de Programación con C++ Abraham Zamudio Chauca 7 / 17
  8. C++14: refinamiento y productividad • Lambdas genéricas con parámetros auto.

    • Deducción del tipo de retorno en funciones. • constexpr más flexible. • Plantillas de variables para constantes y utilidades genéricas. • std::make unique, literales binarios 0b1010 y separadores 1’000’000. Fundamentos de Programación con C++ Abraham Zamudio Chauca 8 / 17
  9. C++14: ası́ se refinó #include <iostream> #include <vector> #include <memory>

    int main() { // 5. Literales binarios y separadores int bin = 0b10101010; // 170 int millon = 1’000’000; // Separadores // 1. Plantillas de variables template<typename T> constexpr T PI = T(3.14159265); // 6. make_unique (nuevo en C++14) auto ptr = std::make_unique<int>(42); // 2. Deduccion de retorno automatica template<typename T> constexpr auto area_circulo(T r) { return PI<T> * r * r; } // 7. Lambda GENERICA con auto auto procesar = [](auto val) { auto cuadrado = val * val; auto area = area_circulo(val); return std::make_pair(cuadrado, area); }; // 3. constexpr con bucles (nuevo) constexpr int factorial(int n) { int res = 1; for (int i = 2; i <= n; ++i) { res *= i; // Bucles en constexpr } return res; } // Funciona con int y double auto r1 = procesar(5); auto r2 = procesar(3.14); // 8. Lambda generica con contenedores auto imprimir = [](const auto& cont) { for (const auto& e : cont) std::cout << e << " "; }; // 4. Retorno deducido con logica auto clasificar(int n) { if (n > 0) return "positivo"; if (n < 0) return "negativo"; return "cero"; } std::vector<int> v = {1, 2, 3}; imprimir(v); // 9. constexpr en compilacion constexpr int f5 = factorial(5); return 0; } Fundamentos de Programación con C++ Abraham Zamudio Chauca 9 / 17
  10. C++17: expresividad y biblioteca • Descomposición estructurada: auto [a, b]

    = par;. • if y switch con inicializador; if constexpr. • Deducción de argumentos de plantillas de clases (CTAD). • Biblioteca: std::optional, std::variant, std::any y std::string view. • std::filesystem y algoritmos paralelos. Fundamentos de Programación con C++ Abraham Zamudio Chauca 10 / 17
  11. C++17: ası́ se volvió expresivo #include <iostream> #include <string> #include

    <string_view> #include <optional> #include <variant> #include <filesystem> int main() { // CTAD: deduccion de tipos de plantilla Config config; config.set("puerto", 8080); config.set("host", std::string("localhost")); // if con inicializador if (auto val = config.get("puerto"); val) { std::visit([](const auto& v) { std::cout << v << "\n"; }, *val); } namespace fs = std::filesystem; struct Config { std::map<std::string, std::variant<int, std::string, bool>> data; // string_view: referencia sin copiar void set(std::string_view k, auto v) { data[std::string(k)] = v; } // Descomposicion estructurada std::tuple<std::string, int> tupla{"servidor", 80}; auto [nombre, puerto] = tupla; std::cout << nombre << ":" << puerto << "\n"; // optional: valor que puede no existir auto get(std::string_view k) const { auto it = data.find(std::string(k)); if (it != data.end()) return it->second; return std::variant<int, std::string, bool>{}; } // switch con inicializador switch (int codigo = 200; codigo) { case 200: std::cout << "OK\n"; break; } // filesystem: navegacion moderna fs::path ruta = fs::current_path(); for (const auto& entry : fs::directory_iterator(ruta)) { if (entry.is_regular_file()) { std::cout << entry.path().filename() << "\n"; } } }; // if constexpr: decision en compilacion template<typename T> void procesar(const T& v) { if constexpr (std::is_integral_v<T>) { std::cout << "Entero: " << v; } else if constexpr (std::is_same_v<T, std::string>) { std::cout << "Texto: " << v; } } procesar(42); procesar(std::string("hola")); return 0; } Fundamentos de Programación con C++ Abraham Zamudio Chauca 11 / 17
  12. Contraste: C++14 vs C++17 C++14: refinamiento C++17: expresividad 1. Desempaquetar

    tuplas con std::tie 1. Descomposición estructurada std::tuple<std::string, int> t{"srv", 80}; std::string nombre; int puerto; std::tie(nombre, puerto) = t; auto t = std::tuple{"srv", 80}; // CTAD auto [nombre, puerto] = t; // claro 2. Valores opcionales: códigos de error int buscar(const std::string& k); // -1 si no existe: ambiguo y propenso 3. Scope amplio en if auto it = mapa.find(k); if (it != mapa.end()) { std::cout << it->second; } // ’it’ sigue viva fuera del if 2. std::optional: intención explı́cita std::optional<int> buscar(string_view k); if (auto r = buscar(k); r) cout << *r; 3. if con inicializador (scope local) if (auto it = mapa.find(k); it != mapa.end()) { std::cout << it->second; } // ’it’ muere al salir del if Impacto del salto C++17 no añadió caracterı́sticas revolucionarias como C++11, pero eliminó código boilerplate y redujo el ámbito de las variables temporales. Los tipos de vocabulario (optional, variant, any) pasaron de Boost al estándar, dando al lenguaje un léxico común para expresar errores, alternativas y valores heterogéneos. Fundamentos de Programación con C++ Abraham Zamudio Chauca 12 / 17
  13. C++20: conceptos, rangos y módulos • Conceptos para expresar restricciones

    de plantillas de forma clara. • Módulos como alternativa moderna a las cabeceras tradicionales. • Corrutinas y std::ranges para componer operaciones sobre secuencias. • Operador de comparación de tres vı́as <=> y std::format. • std::span, std::jthread, consteval y constinit. Fundamentos de Programación con C++ Abraham Zamudio Chauca 13 / 17
  14. C++20: ası́ se volvió potente #include <iostream> #include <vector> #include

    <ranges> #include <concepts> #include <format> #include <span> int main() { // 6. std::format: formateo moderno std::cout << std::format("Pi = {:.3f}\n", std::numbers::pi); // 7. Conceptos en accion auto r1 = procesar(42); // int OK auto r2 = procesar(3.14); // double OK // procesar("texto"); // ERROR // 1. Conceptos: restricciones claras template<typename T> concept Numerico = std::integral<T> || std::floating_point<T>; // 8. Comparaciones con <=> Punto p1{1, 2}, p2{3, 4}; std::cout << (p1 < p2); // true std::cout << (p1 == p1); // true template<typename T> concept Imprimible = requires(T x) { { std::cout << x }; }; // 9. consteval en compilacion constexpr int f5 = fact(5); // 2. Uso de conceptos (sintaxis breve) auto procesar(Numerico auto v) { return v * 2; } // 10. Ranges: pipelines de procesamiento std::vector<int> nums = {1,2,3,4,5,6,7,8}; auto resultado = nums | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; }) | std::views::take(3); // 3. Operador <=> (spaceship) struct Punto { double x, y; auto operator<=>(const Punto&) const = default; }; for (int x : resultado) std::cout << x << " "; // 4. consteval: DEBE ser en compilacion consteval int fact(int n) { int r = 1; for (int i = 2; i <= n; ++i) r *= i; return r; } // 5. std::span: vista de datos contiguos void procesar(std::span<int> datos) { for (int x : datos) std::cout << x; } Fundamentos de Programación con C++ // 11. std::span procesar(std::span<int>(nums).subspan(2, 3)); // 12. std::jthread: auto-join std::jthread hilo([]{ std::cout << "trabajando"; }); return 0; } Abraham Zamudio Chauca 14 / 17
  15. C++23: biblioteca y ergonomı́a • std::print y std::println para salida

    formateada más simple. • std::expected para manejo de errores sin excepciones. • “Deducing this” (parámetro de objeto explı́cito) y if consteval. • Biblioteca: std::mdspan, std::flat map y std::stacktrace. • Mejoras en std::optional, std::string y rangos. Fundamentos de Programación con C++ Abraham Zamudio Chauca 15 / 17
  16. C++23: ası́ se volvió ergonómico #include <print> #include <expected> #include

    <flat_map> #include <mdspan> int main() { // 4. std::print/println: formateo limpio std::println("=== C++23 ==="); std::print("Pi = {:.3f}\n", 3.14159); // 1. std::expected: errores sin excepciones enum class Error { Vacio, Invalido }; // 5. std::expected en uso for (auto s : {"42", "", "abc"}) { if (auto r = parsear(s); r) { std::println("{} -> {}", s, *r); } else { std::println("{} -> ERROR", s); } } std::expected<int, Error> parsear(std::string_view s) { if (s.empty()) return std::unexpected(Error::Vacio); try { return std::stoi(std::string(s)); } catch (...) { return std::unexpected(Error::Invalido); } } // 6. Deducing this Contador c; c.inc().inc().inc(); std::println("Valor: {}", c.val); // 2. Deducing this: CRTP simplificado template<typename D> struct Base { int val = 0; auto& inc(this auto& self) { ++self.val; return self; } }; // 7. std::flat_map: map eficiente std::flat_map<std::string, int> mapa; mapa["Ana"] = 28; mapa["Luis"] = 35; for (auto [k, v] : mapa) std::println("{}: {}", k, v); // 8. std::mdspan: vista multidimensional std::vector<int> datos = {1,2,3,4,5,6}; std::mdspan m(datos.data(), 2, 3); std::println("m[1,2] = {}", m[1,2]); struct Contador : Base<Contador> {}; // 3. if consteval constexpr int fact(int n) { if consteval { // rama compilacion return n <= 1 ? 1 : n * fact(n-1); } else { // rama ejecucion int r = 1; for (int i = 2; i <= n; ++i) r *= i; return r; } } Fundamentos de Programación con C++ // 9. Rangos: zip std::vector<int> a = {1,2,3}; std::vector<int> b = {4,5,6}; for (auto [x,y] : std::views::zip(a,b)) std::println("{},{}", x, y); return 0; } Abraham Zamudio Chauca 16 / 17
  17. Monte Carlo para π: algoritmo y C++23 C++23 en la

    implementación • std::print/std::println: salida formateada y segura en una sola llamada (sin cout + manipuladores). • Pipeline lazy : views::iota | views::transform genera los puntos al vuelo, sin materializar N elementos en memoria. • ranges::count if: conteo declarativo aplicado directamente sobre el rango. • Apoyo de estándares previos: rangos (C++20) y execution::par unseq (C++17); C++23 aporta print y refina la biblioteca de rangos. x2 + y2 ≤ 1 Fundamento del algoritmo • Se muestrean N puntos uniformes en el cuadrado [0, 1)2. • Hay “acierto” si x 2 + y 2 ≤ 1: un cuarto de disco de área π/4. • Estimador: π̂ = 4K /N, con K = número de aciertos (insesgado: E[π̂] = π). // pipeline lazy: no materializa los N puntos auto pts = std::views::iota(0ULL, N) | std::views::transform([&](size_t) { return Punto{dist(rng), dist(rng)}; }); // conteo declarativo sobre el rango const size_t K = std::ranges::count_if(pts, [](const Punto& p) { return p.dentro(); }); // estimador de Monte Carlo const double pi = 4.0 * double(K) / N; std::println("pi ˜ {:.8f} (N={})", pi, N); • Por la ley de los grandes números, π̂ → π cuando N → ∞. Convergencia y costo p √ Error estándar: σπ̂ = 4 p(1 − p)/N ≈ 1.64/ N, es decir O(N −1/2 ): cuadruplicar N recién duplica la precisión. Como las muestras son independientes, el paralelismo es trivial (par unseq) con speedup casi lineal. Fundamentos de Programación con C++ Abraham Zamudio Chauca 17 / 17