Estructuras de Controlc++funcionesmodularizaciónestructuras-de-control

Funciones en C++

Aprende a crear y usar funciones para organizar y reutilizar tu código

OOI Oaxaca9 de febrero de 20266 min read

¿Qué es una función?

Una función es un bloque de código que realiza una tarea específica. Las funciones permiten:

  • Reutilizar código
  • Organizar el programa en partes más pequeñas
  • Abstraer detalles de implementación

Sintaxis básica

tipo_retorno nombre_funcion(parámetros) {
    // Cuerpo de la función
    return valor;
}

Ejemplo simple

int sumar(int a, int b) {
    return a + b;
}

int main() {
    int resultado = sumar(5, 3);
    cout << resultado << endl;  // 8
    return 0;
}

Funciones sin retorno (void)

void saludar(string nombre) {
    cout << "¡Hola, " << nombre << "!" << endl;
}

int main() {
    saludar("Juan");  // ¡Hola, Juan!
    return 0;
}

Parámetros

Por valor

El parámetro es una copia del valor original:

void duplicar(int x) {
    x = x * 2;
    cout << "Dentro: " << x << endl;  // 20
}

int main() {
    int n = 10;
    duplicar(n);
    cout << "Fuera: " << n << endl;   // 10 (no cambió)
    return 0;
}

Por referencia

El parámetro apunta al valor original:

void duplicar(int& x) {  // Nota el &
    x = x * 2;
}

int main() {
    int n = 10;
    duplicar(n);
    cout << n << endl;  // 20 (sí cambió)
    return 0;
}

Cuándo usar cada uno

Por valorPor referencia
Tipos pequeños (int, char)Arreglos y estructuras grandes
Cuando no quieres modificarCuando necesitas modificar
Es más seguroEs más eficiente

Referencia constante

Para eficiencia sin permitir modificación:

void imprimir(const vector<int>& v) {
    for (int x : v) {
        cout << x << " ";
    }
    cout << endl;
    // v.push_back(5);  // Error: no se puede modificar
}

Valores por defecto

void saludar(string nombre = "Usuario") {
    cout << "Hola, " << nombre << endl;
}

int main() {
    saludar();         // Hola, Usuario
    saludar("María");  // Hola, María
    return 0;
}

Sobrecarga de funciones

Múltiples funciones con el mismo nombre pero diferentes parámetros:

int maximo(int a, int b) {
    return (a > b) ? a : b;
}

int maximo(int a, int b, int c) {
    return maximo(maximo(a, b), c);
}

double maximo(double a, double b) {
    return (a > b) ? a : b;
}

int main() {
    cout << maximo(5, 3) << endl;       // 5
    cout << maximo(5, 3, 7) << endl;    // 7
    cout << maximo(3.14, 2.71) << endl; // 3.14
    return 0;
}

Funciones comunes en competencias

Verificar si es primo

bool esPrimo(int n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;

    for (int i = 3; i * i <= n; i += 2) {
        if (n % i == 0) return false;
    }
    return true;
}

Máximo común divisor

int mcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// Versión recursiva
int mcdRecursivo(int a, int b) {
    return (b == 0) ? a : mcdRecursivo(b, a % b);
}

Mínimo común múltiplo

long long mcm(long long a, long long b) {
    return (a / mcd(a, b)) * b;  // Evita overflow
}

Potencia rápida

long long potencia(long long base, long long exp, long long mod) {
    long long resultado = 1;
    base %= mod;

    while (exp > 0) {
        if (exp % 2 == 1) {
            resultado = (resultado * base) % mod;
        }
        exp /= 2;
        base = (base * base) % mod;
    }

    return resultado;
}

Template para competencias con funciones

#include <bits/stdc++.h>
using namespace std;

#define int long long

int mcd(int a, int b) {
    return b ? mcd(b, a % b) : a;
}

bool esPrimo(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

void solve() {
    int n;
    cin >> n;

    if (esPrimo(n)) {
        cout << "Primo" << endl;
    } else {
        cout << "No primo" << endl;
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

Funciones recursivas

Una función que se llama a sí misma:

int factorial(int n) {
    if (n <= 1) return 1;        // Caso base
    return n * factorial(n - 1); // Llamada recursiva
}

Partes de una función recursiva

  1. Caso base: Condición que detiene la recursión
  2. Caso recursivo: Llamada a sí misma con un problema más pequeño
// Fibonacci recursivo
int fib(int n) {
    if (n <= 1) return n;  // Casos base
    return fib(n - 1) + fib(n - 2);  // Caso recursivo
}

Ejercicios de práctica

Ejercicio 1

Escribe una función que determine si un número es palíndromo.

Ver solución
bool esPalindromo(int n) {
    int original = n;
    int invertido = 0;

    while (n > 0) {
        invertido = invertido * 10 + n % 10;
        n /= 10;
    }

    return original == invertido;
}

Ejercicio 2

Escribe una función que cuente los divisores de un número.

Ver solución
int contarDivisores(int n) {
    int cuenta = 0;
    for (int i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            cuenta++;
            if (i != n / i) cuenta++;
        }
    }
    return cuenta;
}

Ejercicio 3

Escribe una función que intercambie dos variables.

Ver solución
void intercambiar(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

// Con swap de la STL
// swap(a, b);

Siguiente paso

Profundiza en Recursión para resolver problemas de manera elegante.