We've previously seen how we can create booleans - true
or false
values - within our code.
bool isAlive { true };
bool isDead { false };
Booleans are a fundamental data type - they're the standard way we control the flow of our program. Control flow is how we have our program do different things, reacting to user input and the state of our objects.
We'll see more of how we can use booleans to control our programs starting in the Conditional Logic lesson. For now, lets see some of the most common ways we can create and manipulate them.
One of the main ways we create booleans is by using specific operators on other data types, particularly numbers.
Two sequential equals characters, the ==
operator, allows us to compare two numbers. When placed between the numbers, it will return the boolean value true
if they equal, and false
otherwise.
int Level { 10 };
// Level is 10, so isLevel10 will be true
bool isLevel10 { Level == 10 };
// This will be false
bool isLevel15 { Level == 15 };
We can also compare two integer variables:
int Level { 20 };
int TargetLevel { 20 };
// This will be true
bool isTargetLevel { Level == TargetLevel};
We also have the !=
operator, which will do the exact opposite. It will evaluate to true
if the two numbers are not equal, otherwise it will return false
.
int Level { 10 };
bool isNotLevel10 { Level != 10 }; // false
bool isNotLevel15 { Level != 15 }; // true
We have 4 other useful operators we can use with numbers:
>
>=
<
<=
Lets look at some examples:
int Level { 10 };
bool isAboveLevel10 { Level > 10 }; // False
bool isAtLeastLevel10 { Level >= 10 }; // True
bool isBelowLevel10 { Level < 10 }; // False
bool isLevel10OrBelow { Level <= 10 }; // True
Floating point numbers have these operators too, and we can compare float
and int
values freely.
float Health { 100.0 };
bool isHealthy { Health > 50.0 };
bool isMaxHealth { Health >= 100 };
We can also combine maths with the boolean operators:
float MaxHealth { 150.0 };
bool isAbove50Percent { Health / MaxHealth > 0.5 };
After running the following code, what will be the value of MyBoolean
?
bool MyBoolean { 15 > 15 };
After running the following code, what will be the value of MyBoolean
?
bool MyBoolean { 15 >= 10 + 5 };
!
We can invert booleans (ie, converting true
to false
, or false
to true
) using the !
operator, for example:
bool isAlive { true };
bool isDead { !isAlive };
We can combine two or more booleans in order to evaluate more than one thing at once. If we use two ampersands - the &&
operator, we can check if multiple things are true.
int Level = 10;
bool isAlive = true;
// This will be true
bool isReady { Level == 10 && isAlive };
We can also use the or operator denoted by ||
to evaluate if at least one thing is true, in a set of checks. For example:
int Level = 10;
// This will be true
bool isReady { Level == 10 || Level == 20 };
We're not restricted to just combining two booleans. We can combine as many booleans as we want using these operators.
The following sample is using multiple lines of code to initialise a single value. We can add additional space to our code as needed to make things clearer. We talk more about white space in the following section:
int Level = 10;
bool isDead { true };
// This will be true
bool isMilestoneLevel {
Level == 10 || Level == 20 || Level == 30
};
// This will be false
bool canStartQuest {
Level >= 10 && Level <= 20 && !isDead
};
We can use both ||
and &&
operators in the same statement. Typically, when doing this, we will also need to introduce brackets (
and )
in order to specify how our checks get grouped together.
int Level { 10 };
bool isAlive { true };
bool isLevel10Or20AndAlive {
(Level == 10 || Level == 20) && isAlive
};
You may have noticed by now that how you space out your code is not of much importance to the compiler. Spaces, tabs and line breaks are commonly called white space and you can add or remove them as you wish.
The positioning of syntax like }
and ;
is what matters from the compiler's perspective. Line breaks and block of space are to help us humans make the most sense of the code, so you can choose what works best for you.
Lets see some examples:
// We can have multiple statements on one line
int Level { 10 }; int MaxLevel { 50 };
// We can have one statement across multiple lines
bool isAlive {
true
};
// When we do this, indenting can make things clearer
bool isImmortal {
false
};
// Spacing a complicated statement across multiple
// lines can make it a bit easier to follow
bool isReady {
Level == MaxLevel &&
(isAlive || isImmortal) &&
Health / MaxHealth > 0.5f
};
If Level
is an integer value, when is isCorrectLevel
true after running the following code?
bool isCorrectLevel { Level < 10 && Level > 20 };
After running the following code, what is the value of isDead
?
int Health = 0;
bool isImmortal = false;
bool isDead { Health == 0 && !isImmortal };
There are two common mistakes beginners make when working with booleans. The first is forgetting to repeat the variable name when combining booleans, eg:
int Level { 15 };
// This will be true, but we might expect it to be false
bool isReady { Level == 10 || 20 };
Line 3 makes sense in plain language - "is Level
equal to 10 or 20?" - but it's a little too ambiguous for code.
It gets interpreted as (Level == 10) || (20)
Because 20
is considered true, the overall boolean simplifies to false || true
, which further simplifies to true
.
The previous assertion that 20
is true is likely confusing. Programming languages often allow other data types to be treated as booleans.
A value that will be true
when used in a boolean context is often called "truthy", whilst a value that will be converted to false
is "falsy" (or "falsey").
In C++ and most other programming languages, the integer value of 0
is falsy, whilst any other integer, such as 20
, is truthy.
To fix the above mistake, we need to specify the variable we're comparing against each time, as shown below.
int Level { 15 };
// This will now be false
bool isReady { Level == 10 || Level == 20 };
The second most common mistake comes from not using brackets when combining the ||
or &&
operator, in a statement like this:
int Level { 10 };
bool isAlive { false };
// This will be true, because Level == 10
bool isReady {
Level == 10 || Level == 20 && isAlive
};
When booleans combine ||
and &&
, the &&
operators are evaluated first. As a result, line 5 gets interpreted as the following:
Level == 10 || (Level == 20 && isAlive)
Therefore, if Level == 10
the combined boolean will be true
regardless of the value of isAlive
. The code below adds (
and )
in the correct places, to clarify our intent.
int Level { 10 };
bool isAlive { false };
// This will be false, because isAlive is false
bool isReady {
(Level == 10 || Level == 20) && isAlive
};
Lets combine our knowledge of numbers and booleans, and learn how to use the debugger so we can see what is happening inside our programs.
— Fixed syntax error in one of the code examples
— First Published
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way