C Booleans

A boolean represents a yes-or-no value: true or false. C uses booleans for comparisons, decisions, validation flags, loop conditions, and any value that answers a question such as is_ready or has_error.

Modern C provides a convenient bool name, but C also has an older and very important rule: 0 means false, and any nonzero value means true. Understanding both styles will help you read new C code and older C code confidently.

Overview: How Booleans Work

In C99 and later, the standard header <stdbool.h> defines bool, true, and false. In typical C implementations, bool is a small integer type, false has the value 0, and true has the value 1. The important concept is not the exact storage size, but the meaning: a bool variable should store whether something is true.

Before <stdbool.h> existed, C programmers commonly used int values for boolean logic. That older style is still part of the language because conditions such as if, while, and logical operators all treat integer values as truth values. In a condition, 0 is false. Any nonzero value, including 1, 42, and -7, is true.

Comparison operators such as ==, !=, <, >, <=, and >= produce integer results: 1 when the comparison is true and 0 when it is false. Logical operators also produce truth values. && means AND, || means OR, and ! means NOT. These operators are central to writing useful conditions.

Under the hood, a bool is still stored in memory like other scalar values. When you assign a nonzero value to a bool, it is converted to 1. When you assign 0, it stays 0. This normalization is useful: a bool does not preserve whether the original true value was 5 or -3; it only preserves truth.

Syntax

The usual form is to include <stdbool.h>, then declare variables with bool and assign boolean expressions to them.

#include <stdbool.h>

int main(void)
{
    bool name = true;
    bool other_name = false;
    bool result = 10 > 3;

    return (name && !other_name && result) ? 0 : 1;
}
Part Meaning
#include <stdbool.h> Makes bool, true, and false available.
bool name Declares a variable intended to hold a true-or-false value.
true and false Readable names for boolean constants.
10 > 3 A comparison expression that evaluates to true.
result ? 0 : 1 A conditional expression. Here it returns success when result is true.

Examples

Example 1: Storing true and false

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    bool is_logged_in = true;
    bool has_permission = false;

    printf("is_logged_in = %d\n", is_logged_in);
    printf("has_permission = %d\n", has_permission);
    printf("sizeof(bool) = %zu\n", sizeof(bool));

    return 0;
}

Output:

is_logged_in = 1
has_permission = 0
sizeof(bool) = 1

C’s printf function has no special boolean format specifier. Use %d to print a bool as an integer value. This program also prints sizeof(bool); on common modern compilers it is 1 byte, which is what this course environment uses.

Example 2: Comparisons and logical AND

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int score = 82;
    int absences = 1;

    bool passed_score = score >= 70;
    bool good_attendance = absences <= 2;
    bool passed_course = passed_score && good_attendance;

    printf("Passed score: %d\n", passed_score);
    printf("Good attendance: %d\n", good_attendance);
    printf("Passed course: %d\n", passed_course);

    return 0;
}

Output:

Passed score: 1
Good attendance: 1
Passed course: 1

The expression score >= 70 is true, and absences <= 2 is also true. Because both sides of && are true, passed_course becomes true. If either side were false, the whole AND expression would be false.

Example 3: Nonzero values become true

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int raw_error_code = -3;
    int bytes_read = 0;

    bool has_error = raw_error_code;
    bool read_anything = bytes_read;
    bool finished_cleanly = !has_error && !read_anything;

    printf("has_error: %d\n", has_error);
    printf("read_anything: %d\n", read_anything);
    printf("finished_cleanly: %d\n", finished_cleanly);

    return 0;
}

Output:

has_error: 1
read_anything: 0
finished_cleanly: 0

The value -3 is nonzero, so assigning it to has_error stores true, printed as 1. The value 0 stores false. The ! operator reverses truth, so !has_error is false and !read_anything is true; false AND true is false.

Example 4: Returning bool from a function

#include <stdio.h>
#include <stdbool.h>

bool is_valid_percent(int value)
{
    return value >= 0 && value <= 100;
}

int main(void)
{
    int values[] = {100, -5, 73};
    size_t count = sizeof(values) / sizeof(values[0]);

    for (size_t i = 0; i < count; i++) {
        if (is_valid_percent(values[i])) {
            printf("%d is valid\n", values[i]);
        } else {
            printf("%d is invalid\n", values[i]);
        }
    }

    return 0;
}

Output:

100 is valid
-5 is invalid
73 is valid

A function that answers a yes-or-no question is a strong candidate for a bool return type. The function name is_valid_percent makes the meaning clear, and the caller can use the result directly in an if statement.

How It Works Step By Step

When the compiler sees bool passed_score = score >= 70;, it evaluates the comparison first. If score is 82, the comparison is true, so the expression produces 1. That value is stored in the bool variable.

For &&, C uses short-circuit evaluation. It evaluates the left operand first. If the left operand is false, the right operand does not need to be evaluated because the whole AND expression must be false. For ||, if the left operand is true, the right operand does not need to be evaluated because the whole OR expression must be true.

This matters when the right side contains a function call or an expression that must be safe. For example, many programs check that a pointer is not null before using it: the left side protects the right side. You will use that pattern more when studying pointers.

Common Mistakes

Using assignment instead of comparison

A common bug is writing if (is_ready = true) when you meant if (is_ready == true). The single = assigns a value. The double == compares values. Even better, if is_ready is already a bool, write if (is_ready).

Expecting only 1 to be true

In C, true does not mean only 1. In conditions, every nonzero value is true. Code such as if (error_code == true) can be misleading because an error code of -3 is true in a condition but is not equal to 1. Prefer if (error_code != 0) when testing an integer status code, or convert it once into a well-named bool.

Forgetting the header

If you use bool, true, or false, include <stdbool.h>. Without it, a C compiler in normal C mode will not know those names. Older code may use int flags instead, but new beginner-friendly code should normally use bool for boolean state.

Best Practices

  • Use bool for variables and return values that represent yes-or-no facts.
  • Name boolean values as questions or states, such as is_open, has_error, can_retry, or should_stop.
  • Test boolean variables directly: prefer if (is_open) over if (is_open == true).
  • Use explicit comparisons for ordinary integers: write count != 0 or status == 0 when that communicates the real condition.
  • Remember that && and || short-circuit, so order conditions from protective checks to dependent checks.
  • Print booleans with %d, or print words with a conditional expression such as flag ? "true" : "false".

Practice Exercises

  1. Write a program with an int temperature. Store whether it is freezing in a bool is_freezing, then print 1 for freezing and 0 otherwise.
  2. Create a function named is_even that accepts an int and returns bool. Test it with at least three numbers.
  3. Write a program that has bool has_ticket and bool has_id. Use && to decide whether a person can enter an event.

Summary

  • bool, true, and false come from <stdbool.h>.
  • C conditions treat 0 as false and any nonzero value as true.
  • Comparisons and logical operators produce truth values that can be stored in bool variables.
  • && means AND, || means OR, and ! means NOT.
  • Use clear boolean names and direct tests to make conditions easier to read.