Important takeaways

  • branching is a way to make a program behave differently based on Boolean expressions (e.g., involving user input)
  • Two major ways of branching in C++ are: if/else-if/else statements and switch statements
  • Boolean expressions evaluate to true or false and can include test operators (like ==, !=, <, >, etc.) between C++ expressions (like variables and constants)
  • Multiple Boolean expressions can be combined using logical OR (||) and AND (&&) operators, or negated using the NOT (!) operator

Contents

Overview

Example of branching
Start. Get user's bank account number and withdraw amount. Does the user
have enough money? If yes, update user's account and dispense cash. If no, 
void transaction and tell user: insufficient funds. End.

It is rare that we write a program that does exactly one thing every time it runs, never deviating from a strict set of steps. More commonly, we want to write programs that react to inputs from the user or another source and execute one piece of code or another given some condition about the current state of variables.

In \ref, we see a flowchart for an ATM system, where we get data from the user (their bank account number and the amount to withdraw from the account). Rather than just dispensing the money, we first check to ensure the user has sufficient funds in their account to make the withdraw. Based on the outcome of that check, we go down one of two paths: we either update the user's account balance and make the withdraw, or we void the transaction and notify the user about the insufficient funds. We refer to each path as a branch of a program. Each branch contains a set of instructions that should only be executed under certain conditions, and when presented with several parallel branches, the computer can only take one.

In this chapter, we will learn about how to implement branching in C++ and how to construct the conditions (called Boolean expressions) to instruct the computer when to take a branch.

(Back to top)

if statements

The simplest branch structure in C++ is the if statement. It works by running a specified block of code at a point in a program only if a given condition holds. If the condition does not hold, the block of code is skipped entirely.

Let's see how to use if statements; say we want to read a number in from the user and, if the number is less than 10, we'll print out a message. The code might look like this:

A simple program

The general structure is:

We call this thing in the parentheses an Boolean expression. A Boolean expression always evaluates to a Boolean value, so either true or false. A Boolean expression can be:

Here are a few examples of Boolean expressions:

Back to the if statement above. Everything within the curly braces immediately following an if statement is the body of the branch. If the expression evaluates to true, then the block of code inside of the curly braces will be executed; if the expression evaluates to false, then the code inside the curly braces is skipped and will not be executed. The program will pick up just after the ending curly brace.

If the body consists of a single statement, the compiler does not require us to include the curly braces. For example, we can rewrite \ref as follows:

No curly braces

Be careful with this—sometimes programmers start off with no braces because there's only one statement in the body, but then add another statement later and forget to add in the curly braces. This can cause hard-to-spot errors! It is strongly recommended that you always use curly braces to avoid such errors.

(Back to top)

else statements

if statements are good, but it would be nice to say something like: "if x is true, do this, otherwise, do that". Luckily, C++ has a built in statement called else, which goes along with if. Here's the structure:

The else must directly follow an if statements (or an else if statement, which we will learn about next). There is no extra Boolean expression necessary—the body of the else will execute if the body of the if is not executed. Exactly one of them will execute: either the if body or the else body. Similar to if, we do not need the curly braces if there is only a single statement. Here is an updated version of \ref that uses an else to print out an alternative message when the number provided by the user is 10 or greater:

A example of else
(Back to top)

else if statements

C++ has another structure that can be used an if statement, called else if. Use this when you want to test another expression when the previous expression evaluates to false. Here's the general structure:

The final else is optional. In addition, you may have as many else if statements after the initial if. An else if's Boolean expression will only be tested if none of the previous Boolean expressions in the current set of branches evaluated to true. If its Boolean expression evalautes to true, then its body is executed and subsequent else if's and the final else, if present, will be skipped. It's important to know that when an else statement is present, exactly one branch will be executed—the others will be ignored. If no else statement is present, then it is possible that none of the branches will be executed.

Here is an updated version of \ref that uses an else if to print out an alternative message when the number provided by the user is exactly 10:

A example of else if
(Back to top)

switch statements

For case-based branching where you want to do something when an (not necessarily Boolean) expression evaluates to a particular value, you can also use a switch statement. These can be used with whole number types, like int and long, as well as char types. Here's the structure:

Here, the expression can be any code that evaluates to a whole number value, e.g., an int or char. Each case within the curly braces covers one of the possibilities, where val1, val2, etc. are the individual values you want to test against (these must be constant expressions—expressions that involve only literals or constants; nothing that can vary during runtime). You need a break statement at the end of each case, or else the code within the next case will be run (sometimes you want that). Finally, the default at the end is somewhat analogous to an else statement; it's is triggered when no other case matches (or when the previous case doesn't end with a break statement). Here's an example where we use a switch statement to determine what choice the user just entered:

An example of a switch statement

I mentioned above that sometimes we want to leave break statements out so we can run the code in the following case statement. Below is an adaptation of \ref that is agnostic of the capitalization of the input character (so 'k' and 'K' are both valid to keep going, and 'q' or 'Q' are valid for quitting).

An example of a switch statement
(Back to top)

Complex Boolean expressions

We talked a little bit about complex Boolean expressions in Section \ref; in this section, we will elaborate on these expressions further and provide additional examples. First, let's start with an example. Suppose that we want a program that asks the user how happy they are on a scale of 1–10. If we want only numbers in that range, then we had better check to make sure the user did that correctly. To check it, we need to make sure the number they provide is greater than or equal to 1 and also less then or equal to 10. That's really two subexpressions: the first compares the input to 1, the second compares the input to 10. If the number is between 1 and 10 (inclusive), then both expressions will evaluate to true. So, we can use the logical "and" operator, &&, between the two sub expressions. Here's what the program looks like:

Range check

Looking at the expression rating >= 1 && rating <= 10, you may be wondering why this is evaluated as (rating >= 1) && (rating <= 10) and not (rating >= 1 && rating) <= 10 (strangely, this will actually evaluate to true as long as rating is greater than or equal to 1). The reason is operator precedence.

Operator Precedence

Just like in algebra, certain operators are evaluated before others, regardless of their place in the expression being evaluated. For example, 10 + 3 * 5 is evaluated as 10 + (3*5), not (10 + 3) * 5. This is because multiplication has a higher precedence than addition. In C++, we have the usual operators, plus many additional ones. Their order of precedence is shown in the table below. Operators in the same tier are evaluated in order from left to right.

Operator Precedence
Relative precedence Operators
Highestx++, x--
! (not)
*, /, % (modulo)
+, -
>, >=, <, <=
==, !=
&&
||
Lowest=, +=, -=, *=, /=

Just as in algebra, you may override any order of precedent by using parentheses to group subexpressions. For more information about operator precedence (including operators will have not yet encountered), see this page.

De Morgan's Laws

Turning back to our example, our if statement checks if the user's input is in the valid range. What we really want is to check if it's not in the valid range, and if so, exit the program. If the rating is valid, then the code that exits the program will be skipped and we can carry on doing whatever we want with the valid range. To do this, we have a couple of options...

Option 1. The obvious thing we can do is to wrap our original expression in parentheses and negate it using the logical "not" operator: !. This is a unary operator and is placed just before the expression we want to negate.

Option 1

Option 2. We can change the if statement so that we check if the rating is less than 1 or is greater than 10. This requires the logical "or" operator: ||. Here's what Option 2 looks like:

Option 2

De Morgan's Laws. We can actually go from Option 1 to Option 2 algebraically by distributing the logical not into the expression. To do this, we use De Morgan's Laws. The two laws say the following:

Note that x and y are placeholders for arbitrary expressions. We distribute the not to all subexpressions inside and flip the operator. In the case of test operators, we don't distribute the not to the operands, but we do flip the operator as follows:

So, if we have the Boolean expression from method 1, we can distribute the not as follows:

(Back to top)