Menu

If else en C: sintaxis, ejemplos y errores comunes

Cómo decide C: la sentencia if, else, las cadenas else if, el anidamiento y el operador ternario, más la regla de la veracidad (0 es falso, todo lo demás es verdadero) y el error de = frente a == que rompe condiciones en silencio.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Por qué los programas necesitan ramas

Todos los programas hasta ahora se han ejecutado de corrido: línea 1, línea 2, línea 3. Los programas reales toman decisiones. ¿La contraseña es correcta? ¿El número es negativo? ¿Se abrió el archivo? La sentencia if es como C hace una pregunta y ejecuta código solo cuando la respuesta es sí.

La condición temperature > 30 se comprueba una vez. Se cumple, así que el mensaje se imprime. La última línea está fuera de las llaves, así que se imprime pase lo que pase. Cambia 31 por 18 y ejecútalo de nuevo: el primer mensaje desaparece y el segundo se queda.

Sintaxis: paréntesis, llaves y ningún punto y coma

Un if en C tiene una forma fija:

if (condicion) {
    // se ejecuta cuando la condicion es distinta de cero
}

Tres reglas que conviene memorizar temprano. Los paréntesis alrededor de la condición son obligatorios. No existe la palabra clave then. Y no va punto y coma después del paréntesis de cierre: uno suelto termina la sentencia ahí mismo.

// BUG: el if no hace nada; el printf se ejecuta siempre
if (x > 10);
{
    printf("grande\n");
}

Eso compila sin quejas. El ; es una sentencia vacía que se convierte en el cuerpo del if, y las llaves de abajo son solo un bloque suelto que siempre se ejecuta. Compilar con gcc -Wall lo detecta.

Las llaves en sí son opcionales para una sola sentencia, pero déjalas. Un if sin llaves al que después le crece una segunda línea es una fuente clásica de errores, porque en C la indentación no agrupa sentencias.

else y else if

else aporta el otro camino:

Para más de dos resultados, encadena con else if. C comprueba cada condición en orden y se detiene en la primera que se cumple:

Aquí el orden importa enormemente. Como la cadena se detiene en la primera coincidencia, la segunda prueba solo llega a ver puntajes por debajo de 90, y por eso score >= 80 no necesita decir además && score < 90. Escribe la cadena de la condición más restrictiva a la menos, o todos los valores caerán en la primera rama.

El else final es opcional. Inclúyelo siempre que la cadena pretenda cubrir todos los casos; su ausencia significa "si nada coincidió, no hagas nada", lo cual está bien pero debería ser deliberado.

Veracidad: 0 es falso, todo lo demás es verdadero

El núcleo del lenguaje C no tiene un tipo booleano aparte en las condiciones. Un if simplemente pregunta si la expresión es distinta de cero.

Las dos últimas líneas muestran la otra mitad de la regla: los operadores de comparación son expresiones corrientes que producen 1 para verdadero y 0 para falso. Por eso if (5 > 2) funciona: en realidad es if (1).

También es por esto que -3 es verdadero en C. La regla es distinto de cero, no positivo. Si quieres saber si un número es positivo, escribe if (n > 0), no if (n).

C99 agregó <stdbool.h> con un tipo bool de verdad más true y false, que se lee mejor en código nuevo. Por debajo siguen siendo 1 y 0, así que nada de la regla anterior cambia; mira booleanos en C.

Los operadores de comparación y lógicos que usarás en las condiciones:

==   igual a                 &&   Y logico (ambos lados verdaderos)
!=   distinto de             ||   O logico (cualquiera de los dos)
<    menor que               !    NO logico
>    mayor que
<=   menor o igual que
>=   mayor o igual que

&& y || hacen cortocircuito: a && b nunca evalúa b si a es falso, y a || b nunca evalúa b si a es verdadero. Eso es una garantía, no una optimización, así que es seguro escribir if (n != 0 && total / n > 5): la división no puede ejecutarse cuando n es cero.

El error de = frente a ==

Este es el error más común de todos en las condiciones de C:

// BUG: asigna 5 a x y luego evalua 5 (distinto de cero), asi que esto SIEMPRE se ejecuta
if (x = 5) {
    printf("x es cinco\n");
}

C permite la asignación dentro de una expresión, así que la línea es legal. Guarda 5 en x, produce el valor 5, y 5 es distinto de cero: la rama se ejecuta todas y cada una de las veces, y x ha sido sobrescrita en silencio.

Dos defensas. Primero, compila siempre con los avisos activados:

gcc -Wall -Wextra program.c -o program

Tanto GCC como clang señalan "suggest parentheses around assignment used as truth value". Segundo, algunos programadores escriben la constante antes de la variable —if (5 == x)— para que un if (5 = x) mal tecleado sea un error de compilación duro en lugar de un fallo silencioso. Ese estilo es cuestión de gustos; activar los avisos no lo es.

Anidamiento

Un if puede contener otro if. El anidamiento expresa condiciones que solo tienen sentido una vez que otra anterior se cumple:

Dos niveles se leen bien. Cuatro no. Cuando el anidamiento se profundiza, busca una forma de aplanarlo, a menudo combinando condiciones con && o atendiendo primero los casos de fallo y retornando temprano:

// mas plano: atiende las excepciones y luego sigue con el trabajo
if (age < 18)     { printf("Solo para adultos.\n");          return 0; }
if (!hasTicket)   { printf("Por favor compra una entrada.\n"); return 0; }
printf("Bienvenido.\n");

El else colgante

Cuando un if sin llaves está anidado dentro de otro, ¿a qué if pertenece un else? La regla de C: un else se asocia al if sin pareja más cercano, sin importar cómo esté indentado el código.

// El else pertenece al if INTERNO, pese a la indentacion
if (a > 0)
    if (b > 0)
        printf("ambos positivos\n");
else
    printf("a no es positivo\n");   // MAL: se ejecuta cuando a > 0 y b <= 0

La indentación dice que el else va con el if externo. El compilador lo empareja con el interno. Las llaves eliminan la ambigüedad por completo, que es el argumento real para usarlas siempre:

if (a > 0) {
    if (b > 0) {
        printf("ambos positivos\n");
    }
} else {
    printf("a no es positivo\n");
}

El operador ternario

Cuando una rama existe solo para elegir un valor, el operador condicional ? : lo dice en una sola expresión:

Lee cond ? x : y como "si cond entonces x, si no y". Se evalúa exactamente una de las dos ramas, y el conjunto produce un valor, que es por lo que puede asignarse o pasarse como argumento donde una sentencia no podría.

Resérvalo para elecciones simples de valores. Los ternarios anidados (a ? b : c ? d : e) son legales y casi siempre más difíciles de leer que la cadena else if que reemplazan.

Preguntas frecuentes

¿Cómo se escribe una sentencia if else en C?

Pon la condición entre paréntesis y el código entre llaves: if (score >= 60) { printf("Aprobado\n"); } else { printf("Reprobado\n"); }. El bloque else se ejecuta solo cuando la condición es falsa, y en C no existe la palabra clave then.

¿Qué cuenta como verdadero en un if de C?

Cualquier valor distinto de cero. El núcleo de C no tiene un tipo booleano propio en las condiciones, así que if (n) se ejecuta cuando n es cualquier cosa menos 0, y if (!n) solo cuando n es exactamente 0. Los operadores de comparación como == y < producen 1 para verdadero y 0 para falso.

¿Cuál es la diferencia entre = y == en C?

== compara, = asigna. Escribir if (x = 5) asigna 5 a x y luego evalúa 5, que es distinto de cero, así que la rama siempre se ejecuta. Compila sin error, y por eso es el error de principiante más común en las condiciones de C; la mayoría de los compiladores avisan con -Wall.

¿Cómo funciona el operador ternario en C?

condicion ? valorSiVerdadero : valorSiFalso es una expresión que produce uno de dos valores, así que puede ir dentro de una asignación o de un argumento de printf: int max = a > b ? a : b;. Úsalo para elegir un valor, y un if normal cuando necesites ejecutar sentencias.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR