Café y Código

8. Funciones y Tipos de Retorno

Una función es un bloque de código reutilizable diseñado para realizar una tarea específica. En C++, cada función declara explícitamente su tipo de retorno (qué valor devuelve al terminar) y sus parámetros (qué datos necesita para trabajar).

1. Ejemplos Fundamentales y Sencillos

Comencemos observando funciones básicas con los casos de uso más cotidianos:

A. Suma de dos números (Retorno int o double)

Una función de tipo int toma dos enteros y devuelve la suma resultante con la palabra clave return.

Suma de dos números
CPP
1#include <iostream>
2
3// Función que recibe dos enteros y devuelve su suma
4int sumar(int a, int b) {
5 return a + b;
6}
7
8int main() {
9 int resultado = sumar(15, 30);
10 std::cout << "La suma es: " << resultado << "\n"; // 45
11 return 0;
12}

B. Calculadora básica (Retornos según la operación)

Podemos crear funciones para cada operación de una calculadora (sumar, restar, multiplicar, dividir):

Operaciones de Calculadora
CPP
1#include <iostream>
2
3double multiplicar(double a, double b) {
4 return a * b;
5}
6
7double dividir(double a, double b) {
8 if (b == 0) {
9 std::cout << "Error: No se puede dividir por cero.\n";
10 return 0.0;
11 }
12 return a / b;
13}
14
15int main() {
16 std::cout << "Multiplicación: " << multiplicar(4.5, 2.0) << "\n"; // 9.0
17 std::cout << "División: " << dividir(10.0, 4.0) << "\n"; // 2.5
18 return 0;
19}

C. Formatear Nombre Completo (Retorno std::string)

Una función que recibe el nombre y el apellido y los une (concatena) devolviendo un std::string completo:

Concatenar Nombre Completo
CPP
1#include <iostream>
2#include <string>
3
4std::string obtenerNombreCompleto(std::string nombre, std::string apellido) {
5 return nombre + " " + apellido;
6}
7
8int main() {
9 std::string cliente = obtenerNombreCompleto("María", "González");
10 std::cout << "Cliente registrado: " << cliente << "\n"; // María González
11 return 0;
12}

D. Verificación de Estado (Retorno bool)

Las funciones de tipo bool devuelven true o false y son muy útiles para evaluar condiciones:

Validación de Estado con Booleano
CPP
1#include <iostream>
2
3// Verifica si el usuario es mayor de edad
4bool esMayorDeEdad(int edad) {
5 return edad >= 18;
6}
7
8// Verifica si un servidor está activo según su código de estado
9bool esEstadoActivo(int codigoEstado) {
10 return codigoEstado == 200; // 200 OK
11}
12
13int main() {
14 int edadUsuario = 20;
15 if (esMayorDeEdad(edadUsuario)) {
16 std::cout << "Acceso permitido.\n";
17 }
18
19 int estadoHttp = 200;
20 if (esEstadoActivo(estadoHttp)) {
21 std::cout << "Servidor en línea (Estado 200 OK).\n";
22 }
23
24 return 0;
25}

E. Función sin Retorno (void)

Cuando una función solo realiza acciones (imprimir en consola, guardar datos) y no necesita entregar un valor de regreso, su tipo de retorno debe ser void.

Función void (sin retorno)
CPP
1#include <iostream>
2
3void saludarUsuario(std::string nombre) {
4 std::cout << "¡Hola, " << nombre << "! Bienvenido al curso de C++.\n";
5 // No requiere instrucción return
6}
7
8int main() {
9 saludarUsuario("Lucas");
10 return 0;
11}

2. Anatomía de una Función y Prototipos

En C++ las funciones deben declararse antes de ser utilizadas. En programas o librerías grandes es una buena práctica separar la declaración (prototipo) de la definición (cuerpo de la función).

Prototipo y Definición
CPP
1#include <iostream>
2
3// 1. Prototipo (declaración)
4int restar(int a, int b);
5
6int main() {
7 int diff = restar(50, 20);
8 std::cout << "Diferencia: " << diff << "\n"; // 30
9 return 0;
10}
11
12// 2. Definición (cuerpo)
13int restar(int a, int b) {
14 return a - b;
15}

3. Resumen de Todos los Tipos de Retorno Posibles en C++

A medida que avanzas en C++, descubrirás que las funciones pueden retornar tipos de datos mucho más complejos:

Tipo de RetornoDescripción / Caso de UsoSintaxis / Ejemplo
voidNo devuelve ningún valor (solo ejecuta acciones).void saludar()
Tipos Primitivos (int, double, bool, char)Devuelven un único valor numérico, lógico o carácter.int sumar(int a, int b)
Cadenas (std::string)Devuelve un texto formateado o procesado.std::string getNombre()
Estructuras / Clases (struct / class)Devuelve un objeto personalizado agrupando varios campos.Persona crearPersona()
Colecciones (std::vector)Devuelve un arreglo dinámico o lista completa de datos.std::vector<int> obtenerPares()
std::pair<T1, T2>Devuelve exactamente dos valores a la vez.std::pair<int, bool> buscar()
std::tuple<T1, T2, T3...>Devuelve tres o más valores sin crear un struct.std::tuple<string, int, double>
std::optional<T> (C++17)Devuelve un valor que puede o no existir (búsquedas o cálculos fallidos).std::optional<double> dividir()
Referencias (T& o const T&)Devuelve un alias directo al objeto original para modificarlo o evitar copias.const std::string& getNombre()
Deducción de Tipo (auto) (C++14)El compilador deduce automáticamente el tipo de retorno.auto multiplicar(double a, double b)

4. Retornos Avanzados en Código

A. Retorno de Múltiples Valores (std::pair y std::tuple)

Retorno Múltiple con Pair y Tuple
CPP
1#include <iostream>
2#include <utility> // std::pair
3#include <tuple> // std::tuple
4
5// Retorna el mínimo y el máximo de dos números
6std::pair<int, int> obtenerMinMax(int a, int b) {
7 if (a < b) return { a, b };
8 return { b, a };
9}
10
11// Retorna tres datos: (Nombre, Edad, Calificación)
12std::tuple<std::string, int, double> obtenerFichaEstudiante() {
13 return { "Ana Gómez", 21, 9.5 };
14}
15
16int main() {
17 // Desempaquetado con Structured Binding (C++17)
18 auto [minimo, maximo] = obtenerMinMax(42, 18);
19 std::cout << "Mínimo: " << minimo << ", Máximo: " << maximo << "\n";
20
21 auto [nombre, edad, promedio] = obtenerFichaEstudiante();
22 std::cout << nombre << " tiene " << edad << " años. Promedio: " << promedio << "\n";
23
24 return 0;
25}

B. Búsqueda y Manejo de Errores con std::optional (C++17)

Operaciones Seguras con std::optional
CPP
1#include <iostream>
2#include <optional>
3
4// Devuelve un resultado opcional
5std::optional<double> dividirSeguro(double a, double b) {
6 if (b == 0.0) return std::nullopt; // Indica ausencia de resultado
7 return a / b;
8}
9
10int main() {
11 auto res1 = dividirSeguro(10.0, 2.0);
12 if (res1.has_value()) {
13 std::cout << "Resultado de la división: " << res1.value() << "\n"; // 5
14 }
15
16 auto res2 = dividirSeguro(5.0, 0.0);
17 if (!res2) {
18 std::cout << "Operación fallida: División por cero.\n";
19 }
20
21 return 0;
22}

5. Paso de Parámetros: Valor, Referencia y const

Al definir los argumentos de una función:

  • Por Valor (int x): Se crea una copia independiente.
  • Por Referencia (int &x): Modificar x cambia la variable original.
  • Por Referencia Constante (const std::string &s): No hace copias pesadas y garantiza que el valor original no sea modificado.
Parámetros por Referencia y Const
CPP
1#include <iostream>
2#include <string>
3
4void duplicar(int& n) {
5 n *= 2; // Altera la variable original
6}
7
8void mostrarMensaje(const std::string& msj) {
9 std::cout << "Mensaje: " << msj << "\n"; // Eficiente y seguro
10}
11
12int main() {
13 int valor = 20;
14 duplicar(valor);
15 std::cout << "Valor duplicado: " << valor << "\n"; // 40
16
17 std::string texto = "Aprendiendo C++";
18 mostrarMensaje(texto);
19
20 return 0;
21}

👨‍💻 Ejercicio Práctico 1

Misión: Función de Calculadora Básica

Escribe una función double calcularAreaTriangulo(double base, double altura) que devuelva el área de un triángulo ((base * altura) / 2). Pruébala en main().

👁️ Ver solución propuesta
CPP
1#include <iostream>
2
3double calcularAreaTriangulo(double base, double altura) {
4 return (base * altura) / 2.0;
5}
6
7int main() {
8 double area = calcularAreaTriangulo(10.0, 5.0);
9 std::cout << "El área del triángulo es: " << area << "\n"; // 25.0
10 return 0;
11}

👨‍💻 Ejercicio Práctico 2

Misión: Verificación de Estado de Usuario

Crea una función bool esCuentaValida(std::string usuario, std::string clave) que devuelva true solo si el usuario es "admin" y la clave es "1234".

👁️ Ver solución propuesta
CPP
1#include <iostream>
2#include <string>
3
4bool esCuentaValida(std::string usuario, std::string clave) {
5 return (usuario == "admin" && clave == "1234");
6}
7
8int main() {
9 if (esCuentaValida("admin", "1234")) {
10 std::cout << "¡Bienvenido Administrador!\n";
11 } else {
12 std::cout << "Credenciales incorrectas.\n";
13 }
14 return 0;
15}
Modo Simulador Express

¿Listo para el Desafío de Funciones en C++?

Pon a prueba tu agilidad con una ronda interactiva de 10 ejercicios aleatorios (autocompletado y depuración de errores) con feedback inmediato y sistema de puntuación.

Iniciar Desafíos Express🚀

Dato curioso: C++ apareció en 1985; Bjarne Stroustrup en Bell Labs. Wikipedia

Ko-fi
Donaciones
Apoyá cafeycodigo con un café en Ko-fi. Colaboradores: insignia, muro y zona exclusiva.