Módulo 03: Operadores

Objetivos del módulo

  • Conocer todos los operadores disponibles en C#
  • Aprender a usar operadores aritméticos, relacionales y lógicos
  • Entender la precedencia de operadores
  • Dominar los operadores de asignación compuesta
  • Conocer los operadores modernos: null-coalescing, null-conditional y pattern matching

1. ¿Qué es un operador?

📘 Concepto: Un operador es un símbolo que le dice al compilador que realice una operación específica sobre uno o más valores. Por ejemplo, el + es un operador que suma dos números o concatena dos textos.


2. Operadores aritméticos

Realizan operaciones matemáticas básicas:

Operador Nombre Ejemplo Resultado
+ Suma 5 + 3 8
- Resta 10 - 4 6
* Multiplicación 6 * 7 42
/ División 15 / 4 3 (¡enteros!)
% Módulo (resto) 15 % 4 3

Ejemplo completo

int a = 15;
int b = 4;

Console.WriteLine($"Suma:           {a} + {b} = {a + b}");      // 19
Console.WriteLine($"Resta:          {a} - {b} = {a - b}");      // 11
Console.WriteLine($"Multiplicación: {a} * {b} = {a * b}");      // 60
Console.WriteLine($"División:       {a} / {b} = {a / b}");      // 3  ← ¡Sin decimales!
Console.WriteLine($"Módulo (resto): {a} % {b} = {a % b}");      // 3

La trampa de la división entera

⚠️ Importante: Cuando divides dos int, el resultado es otro int (se pierden los decimales). 15 / 4 da 3, no 3.75.

// División entera (ambos son int)
int resultadoEntero = 15 / 4;
Console.WriteLine(resultadoEntero);  // 3 (se pierden los decimales)

// División decimal (al menos uno debe ser double o decimal)
double resultadoDecimal = 15.0 / 4;
Console.WriteLine(resultadoDecimal);  // 3.75

// Forzar división decimal con casting
double resultadoCast = (double)15 / 4;
Console.WriteLine(resultadoCast);  // 3.75

El operador módulo (%)

El módulo devuelve el resto de una división. Es muy útil en programación:

// ¿Es un número par o impar?
int numero = 7;
int resto = numero % 2;
Console.WriteLine($"{numero} % 2 = {resto}");  // 1 (impar, porque al dividir 7/2 sobra 1)

// Más ejemplos
Console.WriteLine($"10 % 3 = {10 % 3}");  // 1 (10 = 3×3 + 1)
Console.WriteLine($"20 % 5 = {20 % 5}");  // 0 (división exacta)
Console.WriteLine($"7 % 4 = {7 % 4}");    // 3 (7 = 4×1 + 3)

💡 Consejo: numero % 2 == 0 es la forma clásica de comprobar si un número es par. Si el resto de dividir entre 2 es 0, es par; si es 1, es impar.


3. Operadores de incremento y decremento

Operador Nombre Equivalente
++ Incremento (sumar 1) x = x + 1
-- Decremento (restar 1) x = x - 1
int contador = 10;

contador++;  // Ahora vale 11
Console.WriteLine(contador);  // 11

contador--;  // Ahora vale 10
Console.WriteLine(contador);  // 10

// Pre-incremento vs Post-incremento
int x = 5;
Console.WriteLine(x++);  // Muestra 5, DESPUÉS incrementa a 6
Console.WriteLine(x);    // 6

int y = 5;
Console.WriteLine(++y);  // Incrementa PRIMERO a 6, muestra 6
Console.WriteLine(y);    // 6

Diferencia entre x++ y ++x:

Forma Comportamiento Ejemplo: si x = 5
x++ (post) Usa el valor actual, luego incrementa Console.Write(x++) → muestra 5, x queda en 6
++x (pre) Incrementa primero, luego usa el valor Console.Write(++x) → muestra 6, x queda en 6

💡 Consejo: Para principiantes, recomiendo usar siempre x++ o x-- en líneas separadas para evitar confusiones:

// Claro y sin ambigüedades:
contador++;
Console.WriteLine(contador);

4. Operadores de asignación

Operador Ejemplo Equivalente
= x = 10 Asigna 10 a x
+= x += 5 x = x + 5
-= x -= 3 x = x - 3
*= x *= 2 x = x * 2
/= x /= 4 x = x / 4
%= x %= 3 x = x % 3
int puntos = 100;

puntos += 50;    // puntos = 100 + 50 = 150
Console.WriteLine($"Después de sumar 50: {puntos}");

puntos -= 30;    // puntos = 150 - 30 = 120
Console.WriteLine($"Después de restar 30: {puntos}");

puntos *= 2;     // puntos = 120 * 2 = 240
Console.WriteLine($"Después de multiplicar por 2: {puntos}");

puntos /= 3;     // puntos = 240 / 3 = 80
Console.WriteLine($"Después de dividir entre 3: {puntos}");

puntos %= 7;     // puntos = 80 % 7 = 3 (80 = 7×11 + 3)
Console.WriteLine($"Resto de dividir entre 7: {puntos}");

5. Operadores de comparación (relacionales)

Comparan dos valores y devuelven un bool (true o false):

Operador Significado Ejemplo Resultado
== Igual a 5 == 5 true
!= Distinto de 5 != 3 true
> Mayor que 5 > 3 true
< Menor que 5 < 3 false
>= Mayor o igual que 5 >= 5 true
<= Menor o igual que 5 <= 3 false

⚠️ Importante: No confundas = (asignación) con == (comparación). x = 5 asigna el valor 5 a x. x == 5 pregunta si x es igual a 5.

int edad = 20;
int required = 18;

Console.WriteLine($"edad == 20: {edad == 20}");     // True
Console.WriteLine($"edad != 18: {edad != 18}");     // True
Console.WriteLine($"edad > 18:  {edad > required}");// True
Console.WriteLine($"edad < 18:  {edad < required}");// False
Console.WriteLine($"edad >= 18: {edad >= required}");// True
Console.WriteLine($"edad <= 18: {edad <= required}");// False

// Comparación de strings
string nombre = "Ana";
Console.WriteLine($"nombre == \"Ana\": {nombre == "Ana"}");  // True
Console.WriteLine($"nombre != \"Luis\": {nombre != "Luis"}");// True

6. Operadores lógicos

Combinan expresiones booleanas:

Operador Nombre Descripción Ejemplo
&& AND (Y) Verdadero si ambos son verdaderos true && falsefalse
\|\| OR (O) Verdadero si al menos uno es verdadero true \|\| falsetrue
! NOT (NO) Invierte el valor !truefalse

Tablas de verdad

AND (&&): Ambos deben ser true

A B A && B
true true true
true false false
false true false
false false false

OR (||): Al menos uno debe ser true

A B A || B
true true true
true false true
false true true
false false false

NOT (!): Invierte

A !A
true false
false true

Ejemplo práctico

int edad = 25;
bool tieneCarnet = true;
bool tieneMultas = false;

// AND: Puede conducir si tiene edad Y carnet
bool puedeConducir = (edad >= 18) && tieneCarnet;
Console.WriteLine($"¿Puede conducir? {puedeConducir}");  // True

// OR: Tiene restricción si es menor de edad O tiene multas
bool tieneRestriccion = (edad < 18) || tieneMultas;
Console.WriteLine($"¿Tiene restricción? {tieneRestriccion}");  // False

// NOT: No tiene multas
bool sinMultas = !tieneMultas;
Console.WriteLine($"¿Está sin multas? {sinMultas}");  // True

// Combinados
bool conductorEjemplar = puedeConducir && !tieneMultas;
Console.WriteLine($"¿Conductor ejemplar? {conductorEjemplar}");  // True

📘 Concepto: Los operadores && y || usan evaluación de cortocircuito: si el primer operando ya determina el resultado, no evalúa el segundo. Por ejemplo, en false && algo, como el primero es false, el resultado siempre será false y no evalúa algo.


7. Operador ternario

El operador ternario ? : es un if/else compacto en una sola línea:

// Sintaxis: condición ? valorSiVerdadero : valorSiFalso

int edad = 20;
string mensaje = (edad >= 18) ? "Mayor de edad" : "Menor de edad";
Console.WriteLine(mensaje);  // "Mayor de edad"

// Es equivalente a:
// if (edad >= 18)
//     mensaje = "Mayor de edad";
// else
//     mensaje = "Menor de edad";

// Más ejemplos
int numero = 7;
string paridad = (numero % 2 == 0) ? "par" : "impar";
Console.WriteLine($"{numero} es {paridad}");  // "7 es impar"

double nota = 6.5;
string resultado = (nota >= 5.0) ? "APROBADO" : "SUSPENSO";
Console.WriteLine($"Nota {nota}: {resultado}");  // "Nota 6.5: APROBADO"

💡 Consejo: El operador ternario es ideal para asignaciones simples basadas en una condición. Si la lógica es compleja, usa if/else para mayor legibilidad.


8. Operadores de nulos

C# tiene operadores especiales para trabajar de forma segura con valores null:

Operador null-coalescing (??)

Devuelve el valor de la izquierda si no es null, o el de la derecha si es null:

string? nombre = null;
string saludo = nombre ?? "Desconocido";
Console.WriteLine(saludo);  // "Desconocido"

nombre = "Ana";
saludo = nombre ?? "Desconocido";
Console.WriteLine(saludo);  // "Ana"

// Con números nulables
int? edad = null;
int edadFinal = edad ?? 0;
Console.WriteLine(edadFinal);  // 0

Operador null-coalescing assignment (??=)

Asigna un valor solo si la variable es null:

string? ciudad = null;
ciudad ??= "Madrid";       // Como es null, le asigna "Madrid"
Console.WriteLine(ciudad);  // "Madrid"

ciudad ??= "Barcelona";    // Como ya NO es null, no hace nada
Console.WriteLine(ciudad);  // "Madrid"

Operador null-conditional (?.)

Accede a una propiedad o método solo si el objeto no es null. Si es null, devuelve null en vez de dar error:

string? texto = null;

// Sin operador ?. esto daría NullReferenceException:
// int longitud = texto.Length;  // ❌ ERROR

// Con ?. es seguro:
int? longitud = texto?.Length;
Console.WriteLine(longitud);  // (nada, es null)

texto = "Hola";
longitud = texto?.Length;
Console.WriteLine(longitud);  // 4

// Combinando ?. con ??
int longitudFinal = texto?.Length ?? 0;
Console.WriteLine(longitudFinal);  // 4

9. Precedencia de operadores

Cuando una expresión tiene varios operadores, C# los evalúa en un orden específico (como en matemáticas, la multiplicación va antes que la suma):

Prioridad Operadores Ejemplo
1 (máxima) () Paréntesis (2 + 3) * 4 = 20
2 !, ++, --, casting (tipo) !true, x++
3 *, /, % 6 * 3 / 2 = 9
4 +, - 5 + 3 - 2 = 6
5 <, >, <=, >= 5 > 3
6 ==, != 5 == 5
7 && true && false
8 \|\| true \|\| false
9 ?: (ternario) x > 0 ? "sí" : "no"
10 (mínima) =, +=, -=, etc. x = 5
// Sin paréntesis: sigue la precedencia
int resultado1 = 2 + 3 * 4;     // 2 + 12 = 14 (multiplicación primero)

// Con paréntesis: fuerza el orden
int resultado2 = (2 + 3) * 4;   // 5 * 4 = 20

Console.WriteLine(resultado1);  // 14
Console.WriteLine(resultado2);  // 20

💡 Consejo: Ante la duda, usa paréntesis. Aunque la precedencia sea la correcta, los paréntesis hacen el código más legible y evitan errores:

// Confuso (¿cuál se evalúa primero?)
bool resultado = edad > 18 && nombre != "" || tienePermiso;

// Claro (los paréntesis aclaran la intención)
bool resultado2 = (edad > 18 && nombre != "") || tienePermiso;

10. Operador is y pattern matching básico

C# tiene operadores modernos para comprobar tipos y patrones:

object valor = 42;

// Comprobar tipo con 'is'
if (valor is int numero)
{
    Console.WriteLine($"Es un entero: {numero}");
}

// Pattern matching con comparaciones
int edad = 25;

string categoria = edad switch
{
    < 0 => "Edad inválida",
    < 13 => "Niño",
    < 18 => "Adolescente",
    < 65 => "Adulto",
    _ => "Jubilado"
};

Console.WriteLine($"Edad {edad}: {categoria}");  // "Edad 25: Adulto"

📘 Concepto: El pattern matching es una característica moderna de C# que permite hacer comparaciones complejas de forma elegante. Lo veremos en profundidad en el módulo de estructuras de control.


11. La clase Math

C# incluye la clase Math con funciones matemáticas útiles:

// Potencia
Console.WriteLine($"2^10 = {Math.Pow(2, 10)}");        // 1024

// Raíz cuadrada
Console.WriteLine($"√144 = {Math.Sqrt(144)}");          // 12

// Valor absoluto
Console.WriteLine($"|−5| = {Math.Abs(-5)}");            // 5

// Máximo y mínimo
Console.WriteLine($"Max(3, 7) = {Math.Max(3, 7)}");    // 7
Console.WriteLine($"Min(3, 7) = {Math.Min(3, 7)}");    // 3

// Redondeo
Console.WriteLine($"Round(4.6) = {Math.Round(4.6)}");  // 5
Console.WriteLine($"Floor(4.9) = {Math.Floor(4.9)}");  // 4 (redondea hacia abajo)
Console.WriteLine($"Ceiling(4.1) = {Math.Ceiling(4.1)}"); // 5 (redondea hacia arriba)

// Constantes
Console.WriteLine($"PI = {Math.PI}");       // 3.141592653589793
Console.WriteLine($"E = {Math.E}");         // 2.718281828459045

12. Ejercicios

Ejercicio 1: Calculadora básica

Crea un programa que pida dos números al usuario y muestre el resultado de todas las operaciones aritméticas:

Introduce el primer número: 15
Introduce el segundo número: 4

  15 + 4 = 19
  15 - 4 = 11
  15 * 4 = 60
  15 / 4 = 3.75
  15 % 4 = 3

Ejercicio 2: Área y perímetro

Crea un programa que pida el radio de un círculo y calcule:

  • Área = π × r²
  • Perímetro = 2 × π × r

Usa Math.PI y Math.Pow().

Ejercicio 3: Clasificador de edad

Usando el operador ternario, crea un programa que pida la edad y muestre si la persona es “menor de edad” o “mayor de edad”.

Ejercicio 4: Evaluador de notas

Pide una nota numérica (0-10) y muestra la calificación usando una expresión switch:

  • 0-4.99: Suspenso
  • 5-5.99: Aprobado
  • 6-6.99: Bien
  • 7-8.99: Notable
  • 9-10: Sobresaliente

Ejercicio 5: Cajero automático

Crea un programa que, dada una cantidad de dinero, calcule el mínimo número de billetes y monedas necesarios (billetes de 50€, 20€, 10€, 5€ y monedas de 2€ y 1€):

Introduce la cantidad: 97

Billetes de 50€: 1
Billetes de 20€: 2
Billetes de 10€: 0
Billetes de 5€:  1
Monedas de 2€:   1
Monedas de 1€:   0

Pista: Usa la división entera / y el módulo %.


Resumen

Operador Tipo Ejemplo
+, -, *, /, % Aritméticos 5 + 3, 10 % 3
++, -- Incremento/decremento x++, --y
=, +=, -=, *=, /= Asignación x += 5
==, !=, >, <, >=, <= Comparación x == 5
&&, \|\|, ! Lógicos a && b
? : Ternario x > 0 ? "sí" : "no"
?? Null-coalescing nombre ?? "Sin nombre"
??= Null-coalescing assignment x ??= 0
?. Null-conditional lista?.Count
is Comprobación de tipo/patrón valor is int n