SyntaxStudy
Sign Up
C Logical and Relational Operators
C Beginner 1 min read

Logical and Relational Operators

Relational operators compare two values and produce an integer result: `1` for true and `0` for false. The six relational operators are `==`, `!=`, `<`, `>`, `<=`, and `>=`. A common beginner mistake is using `=` (assignment) where `==` (equality test) is intended. Some compilers warn about this; enabling `-Wall` catches this class of error. The `==` operator compares values, not identity — for pointer comparisons it checks whether both pointers point to the same address. Logical operators combine boolean expressions. `&&` (logical AND) returns true only if both operands are non-zero. `||` (logical OR) returns true if at least one operand is non-zero. `!` (logical NOT) inverts the truthiness of its operand. Both `&&` and `||` use short-circuit evaluation: if the left operand of `&&` is false, the right operand is not evaluated; similarly, if the left operand of `||` is true, the right operand is not evaluated. This property is useful for guarding pointer dereferences. The ternary (conditional) operator `condition ? value_if_true : value_if_false` is C's only operator that takes three operands. It is a compact way to express simple conditional assignments. Nesting ternaries is legal but rapidly becomes unreadable; prefer `if/else` chains for anything beyond simple cases.
Example
#include <stdio.h>

/* Safe division — short-circuit prevents divide-by-zero */
double safe_div(int a, int b)
{
    return (b != 0) ? (double)a / b : 0.0;
}

int main(void)
{
    int x = 5, y = 10;

    /* Relational operators */
    printf("x == y : %d\n", x == y);   /* 0 */
    printf("x != y : %d\n", x != y);   /* 1 */
    printf("x <  y : %d\n", x <  y);   /* 1 */
    printf("x >  y : %d\n", x >  y);   /* 0 */
    printf("x <= 5 : %d\n", x <= 5);   /* 1 */
    printf("x >= 6 : %d\n", x >= 6);   /* 0 */

    /* Logical operators with short-circuit */
    int *ptr = NULL;
    if (ptr != NULL && *ptr > 0) {     /* safe — short-circuits */
        printf("ptr is valid and positive\n");
    } else {
        printf("ptr is NULL — no dereference occurred\n");
    }

    printf("5 || expensive(): %d\n", 1 || (printf("not reached\n"), 0));

    /* Ternary operator */
    int score = 72;
    const char *grade = (score >= 90) ? "A" :
                        (score >= 80) ? "B" :
                        (score >= 70) ? "C" : "F";
    printf("Score %d -> grade %s\n", score, grade);

    printf("safe_div(10, 0) = %.2f\n", safe_div(10, 0));
    printf("safe_div(10, 3) = %.4f\n", safe_div(10, 3));

    return 0;
}