If Statement in C

The C programming language provides the if conditional statement which allows code to be executed only if a condition evaluates to true, that is, different from zero.

Depending on the value of the control condition, the if statement will execute an instruction that can be either simple or compound.

There is also the possibility, through the else clause, to specify an alternative instruction to be executed in the opposite case, that is, when the condition is not met (i.e., is equal to zero).

In this lesson, we will look at the syntax of if statements and else clauses. We will also learn how to handle more complex cases in which it is necessary to chain or nest multiple if statements together.

Key Takeaways
  • An if statement is composed of a control condition and an instruction;
  • The instruction is executed only if the control condition evaluates to a non-zero value, i.e., true;
  • The instruction can be simple or compound, meaning composed of multiple simple instructions;
  • To specify an instruction to be executed when the control condition is false, i.e., zero, the else clause is used;
  • if statements can be chained and nested to handle more complex decision-making cases.

The if Statement

The if statement allows a program to choose between two alternatives by evaluating the result of an expression. In its simplest form, the if statement looks like this:

if ( expression ) statement;

The first thing to note is that the parentheses around the expression are mandatory. Additionally, unlike some other programming languages, the if statement in C does not require a then keyword.

When an if statement is executed, the expression inside the parentheses is evaluated. If the result of the expression is non-zero — which, as we saw in the lesson on logical expressions, is interpreted as true in C — then the instruction that follows is executed.

Using a flowchart, the if statement can be represented as follows:

Flowchart of the if statement
Picture 1: Flowchart of the if statement

In the diagram, the if statement is shown as a diamond containing the condition to be checked. If the condition is true, the instruction is executed; otherwise, control flow continues forward. For this reason, the if statement is a conditional statement.

Definition

The if Statement

An if statement is a conditional statement that allows the execution of an instruction based on the value of a condition.

The syntax of an if statement is as follows:

if (logical_expression)
    statement;

Where logical_expression is a logical expression, meaning it is considered true if its value is non-zero. In that case, the instruction statement is executed.

Let’s clarify with an example:

if (a > b)
    printf("A is greater than B\n");

In this example, the printf instruction is executed if the condition a > b is true, i.e., has a non-zero value.

Note

Be careful not to confuse equality with assignment.

You must be careful, when using the if statement, not to confuse the equality operator == with the assignment operator =.

For example, the following if statement:

if (a == 0)

is very different from this one:

if (a = 0)

In the second case, the expression inside the parentheses, a = 0, assigns zero to the variable a and returns the value 0, which means it always evaluates to false.

Confusing equality (==) with assignment (=) is one of the most common mistakes in C programs. This is likely due to the fact that in mathematics, the equal sign = is used to denote equality, while in C it’s used for assignment.

Some compilers generate a warning if they find an assignment operator where an equality operator is expected, but you should not rely on this feature.

Hint

Checking for a value within a range

Often, in C, the if statement is used to check whether the value of a variable falls within a specific range.

For example, we might want to check if the value stored in variable i lies between 0 and n. In mathematical terms, we want to verify:

0 \leq i \leq n

To do this in C, you can write:

if (0 <= i && i <= n)

On the other hand, if you want to test the opposite condition, you can write:

if (i < 0 || i > n)

Note that in this second case we used the or operator, ||, instead of the and operator, &&.

Compound Statements

Previously, when defining the syntax of the if statement, we used the following form:

if ( expression ) statement;

Note that statement is singular, meaning the if statement can only be followed by a single statement.

How can we make the if statement execute two or more statements? We can use compound statements, which have the following form:

{
    statement_1;
    statement_2;
    /* ... */
    statement_n;
}

In essence, by enclosing a sequence of statements in curly braces, we force the compiler to treat them as a single statement.

Definition

Compound Statements

A compound statement is a statement formed by a sequence of one or more statements enclosed in curly braces. The syntax is as follows:

{
    statement_1;
    statement_2;
    /* ... */
    statement_n;
}

An example of a compound statement is the following:

{
    printf("Inside a compound statement\n");
    a++;
}

Note that the internal statements within the compound statement end with a semicolon, while the compound statement itself does not require a trailing semicolon.

Now we can combine if statements and compound statements as follows:

if (a < b) {
    printf("Inside a compound statement\n");
    a++;
}

The compound statement composed of printf and the increment of variable a will be executed if and only if the condition a < b evaluates to true (i.e., not zero).

The else Clause

An if statement can be followed by an else clause in the following way:

if ( expression ) statement_1; else statement_2;

With this syntax, we are instructing the compiler to execute statement_1 if expression evaluates to a non-zero value, or to execute statement_2 otherwise.

We can represent the else clause with a flowchart like this:

Flowchart of the if statement with else clause
Picture 2: Flowchart of the if statement with else clause

As you can see in the flowchart, the if statement with an else clause allows the control flow to branch into two paths: the true branch, which is followed if the condition is true, and the false branch otherwise.

An example usage of an if statement with an else clause is the following:

if (a < b)
    max = b;
else
    max = a;

Note that both instructions in the two branches are terminated with a semicolon.

Definition

The else Clause

The else clause of an if statement allows for the selection of a statement when the condition evaluates to false. The syntax to use is as follows:

if (condition)
    true_branch_statement;
else
    false_branch_statement;
Hint

Placement of the else Clause

From a syntactic standpoint, the C compiler imposes no constraints on where the else clause is placed.

We can, for example, write code by aligning the else clause with the if statement like this:

if (a < b)
    max = b;
else
    max = a;

Or, if the statements are short, we can be more concise and write everything like this:

if (a < b) max = b;
else max = a;

Nested if Statements

There are no restrictions on the types of statements that can appear inside an if statement. In fact, it's not uncommon to find nested if statements, that is, if statements within other if statements.

Let's look at an example: we want to find the maximum of three integer variables a, b, and c. We can implement the search for the maximum in this way:

/* Find the maximum among a, b, and c */
if (a > b)
    if (a > c)
        max = a;
    else
        max = c;
else
    if (b > c)
        max = b;
    else
        max = c;

Using a flowchart, we can represent the code snippet above like this:

Flowchart of nested if statements in the example
Picture 3: Flowchart of nested if statements in the example

We implemented the maximum search by nesting multiple if statements. There's no limit to the number of if statements that can be nested. The only limit is, probably, the readability of the code. In fact, as the number of nested if statements increases, the code can become particularly complex.

Definition

Nested if Statements

if statements can contain other if statements inside them; in this case, we refer to them as nested if statements.

The general syntax for nesting if statements is as follows:

if (condition_1)
    if (sub_condition_1)
        statement_1;
    else
        statement_2;
else
    if (sub_condition_2)
        statement_3;
    else
        statement_4;

One way to simplify the writing of nested if statements is to use curly braces even when they are not necessary. So, we can rewrite the above code like this:

/* Find the maximum among a, b, and c */
if (a > b) {
    if (a > c)
        max = a;
    else
        max = c;
} else {
    if (b > c)
        max = b;
    else
        max = c;
}

Using curly braces around statements, even when not strictly necessary, is like using parentheses in mathematical expressions: they help make the code more readable and, at the same time, prevent the compiler from interpreting the code differently than intended.

In some cases, it may be useful to add curly braces even around the statements inside nested if statements, like this:

/* Find the maximum among a, b, and c */
if (a > b) {
    if (a > c) {
        max = a;
    } else {
        max = c;
    }
} else {
    if (b > c) {
        max = b;
    } else {
        max = c;
    }
}

Using curly braces in this way has two advantages:

  1. The program is easier to modify since we can quickly add other statements to the if or else clauses;
  2. It avoids errors that may arise from forgetting braces when adding statements to a clause.

Concatenated if Statements

Situations may arise where a program’s decision depends not only on whether a condition is true or false. Rather, the program may need to check a series of conditions and stop as soon as one of them proves true.

In such cases, in C, we can use concatenated if statements.

For example, suppose we want to print a message on the screen that tells us whether the value of an integer variable is less than, equal to, or greater than zero. In this case, we can't use a simple if statement, but we must use two nested ifs, like this:

if (a < 0)
    printf("a è minore di zero\n");
else
    if (a == 0)
        printf("a è uguale a zero\n");
    else
        printf("a è maggiore di zero\n");

Using a flowchart, we can represent the above code like this:

Flowchart of the concatenated if statements in the example
Picture 4: Flowchart of the concatenated if statements in the example

Although the second if statement is nested in the first, in practice we do not use indentation to highlight the second if statement. What we usually do is place the if statements right after the else clauses and align the else clauses with the first if:

if (a < 0)
    printf("a è minore di zero\n");
else if (a == 0)
    printf("a è uguale a zero\n");
else
    printf("a è maggiore di zero\n");

By doing so, concatenated if statements take on a typical appearance:

if ( expression_1 )
    statement_1;
else if ( expression_2 )
    statement_2;
else if ( expression_3 )
    statement_3;
/* ... */
else if ( expression_n )
    statement_n;
else
    final_statement;

This way of indenting concatenated if statements avoids the problem of overly indented code when the number of tests to perform becomes excessive. Moreover, it has the advantage of visually highlighting a simple sequence of tests.

Definition

Concatenated if Statements

Concatenated if statements are if statements that contain another if statement in their else clause, and so on. They are useful when multiple conditions need to be tested and there are multiple distinct cases.

The general form of nested if statements is as follows:

if ( expression_1 )
    statement_1;
else if ( expression_2 )
    statement_2;
else if ( expression_3 )
    statement_3;
/* ... */
else if ( expression_n )
    statement_n;
else
    final_statement;

It should always be remembered that concatenated if statements are not a new type of statement. They are simply ordinary if statements that contain another if statement in their else clause, and so on.

Dangling else Problem

When using nested if statements, you must be careful of the notorious Dangling else problem.

To clarify, let's take the following example:

if (b != 0)
    if (a != 0)
        result = a / b;
else
    printf("Error: b is equal to 0\n");

At first glance, the code above may seem correct. Superficially, it looks like the code first checks if b is different from zero and otherwise prints an error message to avoid division by zero. However, the indentation misleads us.

In reality, the code above is ambiguous because it's not clear to which of the two if statements the else clause belongs. The C language follows the convention of associating an else clause with the nearest preceding if that has not yet been matched to an else.

For this reason, a correctly indented version of the above code is the following:

/* Correctly indented version */
if (b != 0)
    if (a != 0)
        result = a / b;
    else
        printf("Error: b is equal to 0\n");

In this case, the else clause will always be associated with the nearest if. The only way to change this behavior is to use curly braces and force the association to the outer if statement, like so:

/* Version that associates the else with the outer if */
if (b != 0) {
    if (a != 0)
        result = a / b;
} else
    printf("Error: b is equal to 0\n");

The dangling else problem shows the importance of using curly braces. With them, you can make the code unambiguous. In fact, many developers prefer to always use braces even when not strictly necessary to avoid this problem.

Definition

Dangling else Problem

In C, when nested if statements are present and statements are not explicitly enclosed in curly braces, the convention is to associate an else with the nearest unmatched if.

In this case, the else is associated with the second if:

if (condition_1)
    if (condition_2)
        statement_1;
    else
        statement_2;

In this other case, by explicitly using curly braces, the else is associated with the first if:

if (condition_1) {
    if (condition_2)
        statement_1;
} else
    statement_2;

In both cases, code indentation is irrelevant.

In Sintesi

In this lesson, we examined the syntax of conditional if statements in C. We saw how to specify the condition to verify and how to specify the statements to execute when the condition is true (i.e., not zero), and vice versa using the else clause.

For more complex conditions that don't reduce to simple true or false, we saw how to chain multiple if statements. We also explored how to nest multiple if statements, discovering along the way one of the pitfalls that can arise in such cases: the Dangling else problem.

In the next lesson, we will study the second conditional statement provided by the C language: the switch statement.