Ir al contenido principal

Estructuras de decisión: if, else y switch

Introducción

Las estructuras de decisión son elementos fundamentales en cualquier lenguaje de programación, ya que permiten que nuestros programas tomen diferentes caminos de ejecución según se cumplan o no ciertas condiciones. En C#, disponemos principalmente de las estructuras if, else y switch, que nos ayudarán a controlar el flujo de nuestras aplicaciones de manera eficiente.

En este artículo aprenderemos a utilizar estas estructuras para crear programas que puedan tomar decisiones, evaluando condiciones y ejecutando distintos bloques de código según el resultado de dichas evaluaciones. Dominar estas estructuras es esencial para crear aplicaciones dinámicas y capaces de responder a diferentes situaciones.

Estructura if

La estructura if es la forma más básica de control de flujo condicional. Permite ejecutar un bloque de código únicamente si se cumple una condición específica.

Sintaxis básica

if (condición)
{
    // Código que se ejecuta si la condición es verdadera
}

Donde condición es una expresión que se evalúa como un valor booleano (true o false).

Funcionamiento

  1. Se evalúa la condición entre paréntesis.
  2. Si la condición es true, se ejecuta el bloque de código entre llaves.
  3. Si la condición es false, se omite ese bloque y la ejecución continúa con las instrucciones posteriores al if.

Ejemplo práctico

using System;

class ProgramaEdad
{
    static void Main()
    {
        Console.Write("Introduce tu edad: ");
        int edad = Convert.ToInt32(Console.ReadLine());
        
        if (edad >= 18)
        {
            Console.WriteLine("Eres mayor de edad.");
        }
        
        Console.WriteLine("Fin del programa.");
    }
}

En este ejemplo, el mensaje "Eres mayor de edad" solo se mostrará si el usuario introduce un valor mayor o igual a 18. Sin importar la edad introducida, el programa siempre mostrará "Fin del programa".

Estructura if-else

La estructura if-else extiende la funcionalidad del if simple, permitiendo especificar un bloque de código alternativo que se ejecutará cuando la condición sea falsa.

Sintaxis básica

if (condición)
{
    // Código que se ejecuta si la condición es verdadera
}
else
{
    // Código que se ejecuta si la condición es falsa
}

Funcionamiento

  1. Se evalúa la condición entre paréntesis.
  2. Si la condición es true, se ejecuta el bloque de código del if.
  3. Si la condición es false, se ejecuta el bloque de código del else.
  4. En cualquier caso, solo se ejecuta uno de los dos bloques.

Ejemplo práctico

using System;

class ProgramaEdad
{
    static void Main()
    {
        Console.Write("Introduce tu edad: ");
        int edad = Convert.ToInt32(Console.ReadLine());
        
        if (edad >= 18)
        {
            Console.WriteLine("Eres mayor de edad.");
        }
        else
        {
            Console.WriteLine("Eres menor de edad.");
        }
        
        Console.WriteLine("Fin del programa.");
    }
}

En este caso, si la edad es mayor o igual a 18, se mostrará "Eres mayor de edad"; de lo contrario, se mostrará "Eres menor de edad". El mensaje "Fin del programa" siempre se mostrará al finalizar.

Estructura if-else-if

Cuando necesitamos evaluar múltiples condiciones en secuencia, podemos encadenar varios bloques if-else utilizando la estructura if-else-if.

Sintaxis básica

if (condición1)
{
    // Código que se ejecuta si condición1 es verdadera
}
else if (condición2)
{
    // Código que se ejecuta si condición1 es falsa y condición2 es verdadera
}
else if (condición3)
{
    // Código que se ejecuta si condición1 y condición2 son falsas y condición3 es verdadera
}
else
{
    // Código que se ejecuta si todas las condiciones anteriores son falsas
}

Funcionamiento

  1. Las condiciones se evalúan en orden, de arriba hacia abajo.
  2. Tan pronto como se encuentra una condición verdadera, se ejecuta su bloque de código y se omiten todas las condiciones restantes.
  3. Si ninguna condición es verdadera, se ejecuta el bloque else final (si existe).

Ejemplo práctico

using System;

class ClasificacionEdad
{
    static void Main()
    {
        Console.Write("Introduce tu edad: ");
        int edad = Convert.ToInt32(Console.ReadLine());
        
        if (edad < 12)
        {
            Console.WriteLine("Eres un niño.");
        }
        else if (edad < 18)
        {
            Console.WriteLine("Eres un adolescente.");
        }
        else if (edad < 65)
        {
            Console.WriteLine("Eres un adulto.");
        }
        else
        {
            Console.WriteLine("Eres un adulto mayor.");
        }
    }
}

Este programa clasifica al usuario en diferentes categorías según su edad. Primero comprueba si es menor de 12 años, luego si es menor de 18, después si es menor de 65, y finalmente, si no cumple ninguna de las condiciones anteriores (es decir, tiene 65 años o más), lo clasifica como adulto mayor.

Operador condicional ternario

C# proporciona una forma abreviada de escribir ciertas estructuras if-else simples mediante el operador ternario ?:.

Sintaxis básica

resultado = condición ? valorSiVerdadero : valorSiFalso;

Funcionamiento

  1. Se evalúa la condición.
  2. Si es true, la expresión devuelve valorSiVerdadero.
  3. Si es false, la expresión devuelve valorSiFalso.

Ejemplo práctico

using System;

class OperadorTernario
{
    static void Main()
    {
        Console.Write("Introduce tu edad: ");
        int edad = Convert.ToInt32(Console.ReadLine());
        
        string mensaje = (edad >= 18) ? "Eres mayor de edad." : "Eres menor de edad.";
        Console.WriteLine(mensaje);
    }
}

Este ejemplo es equivalente al segundo ejemplo que vimos con if-else, pero utilizando el operador ternario, lo que lo hace más conciso en casos sencillos.

Estructura switch

La estructura switch es útil cuando necesitamos evaluar una expresión contra múltiples valores posibles. Es una alternativa más clara y eficiente que utilizar múltiples bloques if-else-if cuando todas las condiciones comparan la misma variable contra diferentes valores.

Sintaxis básica

switch (expresión)
{
    case valor1:
        // Código a ejecutar si expresión == valor1
        break;
    case valor2:
        // Código a ejecutar si expresión == valor2
        break;
    // Más casos...
    default:
        // Código a ejecutar si ninguno de los casos anteriores coincide
        break;
}

Funcionamiento

  1. Se evalúa la expresión una vez.
  2. Se compara el resultado de la expresión con cada uno de los valores especificados en las cláusulas case.
  3. Cuando se encuentra una coincidencia, se ejecuta el código correspondiente hasta encontrar un break o el final del switch.
  4. Si no hay coincidencias, se ejecuta el bloque default (si existe).

Importancia de break

La instrucción break es crucial en cada caso, ya que indica el final de un bloque case. Sin ella, la ejecución continuaría con el siguiente case, independientemente de si coincide o no (característica conocida como "fall-through").

Ejemplo práctico

using System;

class DiaSemana
{
    static void Main()
    {
        Console.Write("Introduce un número del 1 al 7: ");
        int dia = Convert.ToInt32(Console.ReadLine());
        
        switch (dia)
        {
            case 1:
                Console.WriteLine("Lunes");
                break;
            case 2:
                Console.WriteLine("Martes");
                break;
            case 3:
                Console.WriteLine("Miércoles");
                break;
            case 4:
                Console.WriteLine("Jueves");
                break;
            case 5:
                Console.WriteLine("Viernes");
                break;
            case 6:
                Console.WriteLine("Sábado");
                break;
            case 7:
                Console.WriteLine("Domingo");
                break;
            default:
                Console.WriteLine("Número no válido. Debe ser entre 1 y 7.");
                break;
        }
    }
}

Este programa convierte un número del 1 al 7 en el nombre del día de la semana correspondiente. Si el usuario introduce un número fuera de este rango, se muestra un mensaje de error.

Múltiples casos con la misma acción

En C#, es posible que varios casos compartan el mismo bloque de código:

using System;

class TipoDia
{
    static void Main()
    {
        Console.Write("Introduce un número del 1 al 7: ");
        int dia = Convert.ToInt32(Console.ReadLine());
        
        switch (dia)
        {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                Console.WriteLine("Día laborable");
                break;
            case 6:
            case 7:
                Console.WriteLine("Fin de semana");
                break;
            default:
                Console.WriteLine("Número no válido. Debe ser entre 1 y 7.");
                break;
        }
    }
}

En este ejemplo, los días del 1 al 5 (lunes a viernes) se consideran días laborables, mientras que los días 6 y 7 (sábado y domingo) se consideran fin de semana.

Switch con expresiones pattern-matching (C# 7.0 y posteriores)

A partir de C# 7.0, la instrucción switch se ha mejorado para admitir pattern matching, lo que permite casos más complejos que la simple igualdad:

using System;

class TipoNumero
{
    static void Main()
    {
        Console.Write("Introduce un número: ");
        object valor = Convert.ToInt32(Console.ReadLine());
        
        switch (valor)
        {
            case 0:
                Console.WriteLine("Cero");
                break;
            case int n when n > 0:
                Console.WriteLine("Número positivo");
                break;
            case int n when n < 0:
                Console.WriteLine("Número negativo");
                break;
            default:
                Console.WriteLine("No es un número entero");
                break;
        }
    }
}

En este ejemplo, utilizamos pattern matching para clasificar un número como cero, positivo o negativo.

Expresión switch (C# 8.0 y posteriores)

C# 8.0 introdujo la expresión switch, una forma más concisa de usar switch cuando cada caso devuelve un valor:

using System;

class DiaSemanaExpresion
{
    static void Main()
    {
        Console.Write("Introduce un número del 1 al 7: ");
        int dia = Convert.ToInt32(Console.ReadLine());
        
        string nombreDia = dia switch
        {
            1 => "Lunes",
            2 => "Martes",
            3 => "Miércoles",
            4 => "Jueves",
            5 => "Viernes",
            6 => "Sábado",
            7 => "Domingo",
            _ => "Número no válido. Debe ser entre 1 y 7."
        };
        
        Console.WriteLine(nombreDia);
    }
}

La expresión switch utiliza la sintaxis => para asociar cada caso con su resultado, y _ como comodín que equivale a default.

Tabla comparativa: if-else vs switch

Característica if-else switch
Tipo de comparación Puede evaluar cualquier expresión booleana Principalmente igualdad (==)
Expresiones a evaluar Múltiples expresiones diferentes Una sola expresión contra múltiples valores
Eficiencia Menos eficiente para muchas comparaciones de igualdad Más eficiente para muchas comparaciones de igualdad
Complejidad de condiciones Admite condiciones complejas directamente Requiere pattern matching para condiciones complejas
Legibilidad Mejor para pocas condiciones o muy diferentes Mejor para muchos casos basados en un solo valor

Cuándo usar cada estructura

Usa if-else cuando:

  • Necesites evaluar condiciones booleanas complejas
  • Tengas pocas condiciones a evaluar
  • Las condiciones sean muy diferentes entre sí
  • Necesites comparar rangos o usar operadores diferentes a la igualdad

Usa switch cuando:

  • Debas comparar una sola variable contra múltiples valores constantes
  • Tengas muchos casos posibles
  • Todos los casos se basen en la igualdad con la misma variable
  • Necesites mejorar la legibilidad de un código con muchas comparaciones

Resumen

Las estructuras de decisión son herramientas fundamentales que permiten que nuestros programas tomen diferentes caminos de ejecución según las condiciones que especifiquemos. Hemos aprendido a utilizar if, else y switch para controlar el flujo de nuestras aplicaciones, cada una con sus propias ventajas y casos de uso.

El dominio de estas estructuras es esencial para crear programas dinámicos que puedan responder de manera diferente según las circunstancias. En el próximo tema, profundizaremos en los operadores de comparación y lógicos, que son elementos cruciales para formular las condiciones que utilizamos en estas estructuras de decisión.