Variables, Types and Operators
Learn the fundamentals of C++ programming: declaring variables, using built-in data types, and performing operations with operators
This lesson is a quick introductory tour of variables and operators within C++. It is not intended for those who are entirely new to programming. Rather, the people who may find it useful include:
- those who have completed our introductory course, but want a quick review
- those who are already familiar with programming in another language, but are new to C++
- those who have used C++ in the past, but would benefit from a refresher
It summarises several lessons from our introductory course. For more thorough explanations or additional context, consider completing Chapter 1 of the beginner course.
Intro to C++ Programming
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way
In C++, single line comments start with //
and comment blocks extend from /*
to */
// This is a single-line comment
/*
This is a multiline
comment
*/
Variables and Types
C++ is a strongly typed language, so we always declare the types of our variables. Statements end with a semicolon.
// A boolean - a true or false value
bool MyBoolean;
// An integer such as 42
int MyInteger;
// A floating point number such as 3.14
float MyFloat;
// "Double Precision" floating point numbers
// use extra memory to improve accuracy
double MyDouble;
Variables can be initialized at the same time they are declared. There are several ways of doing this, but we typically use braces {
and }
:
int MyInteger{42};
// Float literals have an f suffix
float MyFloat{5.2f};
double MyDouble{5.2};
bool MyBool{true};
Operators and Expressions
Once they've been created, variables are updated using the assignment operator =
:
int MyInteger{42};
MyInteger = 10;
Literals, variables, and the result of expressions can be used interchangeably:
int MyInteger{2};
int AnotherInt{2 + 2};
int IntegerFromVariable{MyInteger};
int IntegerFromExpression{MyInteger + 1};
White Space
C++ is mostly insensitive to spaces, tabs and line breaks. These are collectively known as white space. We can generally add or remove white space from our code to lay it out in any way we prefer:
int SomeInt{5};
int AnotherInt { 5 };
bool SomeBool {
false
};
bool AnotherBool
{ false };
int A{5}; int B{10}; int C{15};
Automatic Type Deduction
When providing an initial value, we can ask the compiler to infer the type using the auto
keyword.
Note that auto
is not dynamic typing. The type will be fixed once the variable is created:
// Creates a variable of type int
auto MyVariable { 10 };
This should be used sparingly, as visually concealing the types from our code can make it harder to understand and debug.
Type Conversions
C++ performs implicit type conversion at compile time where possible:
// 2.5 (double) converted to 2.5f (float)
float MyFloat { 2.5 };
// 2.0 (double) converted to 2 (int)
int MyInteger { 2.0 };
// 2 (int) converted to 2.0 (double)
double MyDouble = MyInteger;
// 3 (int) converted to 3.0f (float)
float MyFloat = 1 + 2;
We can explicitly ask the compiler to do conversions using static_cast
. The syntax looks like this:
static_cast<type_to_cast_to>(value_to_cast)
For example:
static_cast<int>(2.5); // Returns 2
static_cast<float>(2); // Returns 2.0f
int MyInt { static_cast<int>(2.5f) };
float MyFloat { static_cast<float>(MyInt) };
Narrowing Conversions
There are other ways to initialize variables, including the =
operator, but uniform initialization using {
and }
is recommended. It includes some safeguards against potential human error.
Most notably, uniform initialization will throw a compiler error if we attempt an implicit narrowing conversion which would cause data loss.
For example, if we try to store the floating point value 3.14
in an integer, that may be a mistake on our part. Narrowing 3.14
to an integer means we'll be using the value 3
. This will mean future calculations are less accurate, and we may not even notice.
The compiler allows narrowing casts at initialization if we use =
, but not if we use {
and }
:
// Implicit narrowing conversion allowed
int MyNumber1 = 3.14;
// Implicit narrowing conversion disallowed
int MyNumber2{3.14};
// We make it explicit if this was intended
int MyNumber3{static_cast<int>(3.14)};
conversion from 'double' to 'int', possible loss of data
Numbers
Numbers support all the typical mathematical operators we're familiar with from other programming languages. Below, we demonstrate this with integers, but the techniques work with any numeric type.
int x { 4 };
// Addition
x = x + 2; // x is now 6
// Subtraction
x = x - 2; // x is now 4
// Multiplication
x = x * 2; // x is now 8
// Division
x = x / 2; // x is now 4
Integer Division (Quotient and Modulus)
When dividing integers, the result of 5
divided by 2
is considered to be 2, with 1 remaining.
The /
operator returns the quotient (2
, in this example) whilst %
returns the modulus (1
, in this example)
// Integer division returns the quotient
5 / 2; // 2
// Modulus is available using % operator
5 % 2; // 1
Order of Operations
C++ operators are subject to an order of operations. When these are mathematical operations, the order is equivalent to what we expect from math. For example, multiplication happens before addition:
4 + 2 * 2; // = 4 + 4 = 8
Order of operations can be manipulated by introducing brackets:
(4 + 2) * 2; // = 6 * 2 = 12
Integer and Floating Point Interaction
Different numeric types generally interact in predictable ways. When either operand of division is a floating point number, the result will also be a floating point number
5 / 2.0; // 2.5
5.0 / 2; // 2.5
When a floating point number is directly converted to an integer, the floating point component is discarded
int a = 2.1; // 2
int b = 2.5; // 2
int c = 2.9; // 2
When initializing a variable, the expression is evaluated before considering what type our variable should eventually have:
float a{5 / 2}; // 2.0
Assignment using =
is an operator too, and it is ordered after most other operators:
float a;
a = {5 / 2}; // 2.0
Increment and Decrement Operators
The increment and decrement operators (++
and --
) are available. They can come before the operand (as a prefix operator) or after the operand (as a postfix operator)
The prefix and postfix operators modify their operands in the same way. However, the prefix operators return the new value of the operand, whilst the postfix operator returns the previous value.
int x { 1 };
int y;
y = ++x; // both x and y are now 2
y = x++; // x is now 3, but y is still 2
int x { 1 };
int y;
y = --x; // both x and y are now 0
y = x--; // x is now -1, but y is still 0
Compound Assignment
A variable can be modified in place using the compound assignment operators, +=
, -=
. *=
and /=
.
These are shorthand ways of writing longer expressions. For example, x += 2
is equivalent to x = x + 2
. More examples are below:
int x { 4 };
x += 5; // x is now 9
x -= 5; // x is now 4
x *= 2; // x is now 8
x /= 2; // x is now 4
Floating Point Shorthand
When the decimal component of a floating point number is 0, it can be omitted
float MyFloat { 2.f }; // 2.0f
double MyDouble { 2. }; // 2.0
Thousands Separator
The '
character can be added to numbers for readability. Typically, this is used as a thousands separator for large numbers:
int ABigInteger { 1'000'000'000 };
float ABigFloat { 2'000'000'000.f };
Booleans
Booleans in C++ have the bool
type, and their literal values are either true
or false
bool Bool1 { true };
bool Bool2 { false };
A boolean value in C++ can be generated in the same way as almost every other modern programming language. We have the 6 usual comparison operators:
==
returnstrue
if the two operands are equal!=
returnstrue
if the two operands are not equal>
returnstrue
if the left operand is larger than the right operand>=
returnstrue
if the left operand is larger than or equal to the right operand<
returnstrue
if the left operand is smaller than the right operand<=
returnstrue
if the left operand is smaller than or equal to the right operand
bool MyBool { false };
// The equality operator: ==
MyBool = 5 == 5; // true
// The inequality operator: !=
MyBool = 5 != 5; // false
// The greater than operator: >
MyBool = 5 > 2; // true
MyBool = 5 > 5; // false
// The greater than or equal to operator: >=
MyBool = 5 >= 5; // true
// The less than operator: <
MyBool = 5 < 2; // false
MyBool = 5 < 5; // false
// The less than or equal to operator: <=
MyBool = 5 <= 5; // true;
Combining Booleans
Booleans can be combined using the logical and operator, &&
:
true && true; // true
true && false; // false
// Simplifies to false && true
2 > 5 && 5 > 2; // false
We also have the logical or operator ||
:
true || true; // true
true || false; // true
// Simplifies to false || true
2 > 5 || 5 > 2; // true
Boolean Order of Operations
Similar to other operators, &&
and ||
are subject to an order of operations. We can introduce brackets to control this:
// Simplifies to true && false
MyBool = (true || false) && false; // false
// Simplifies to true || false
MyBool = true || (false && false); // true
Boolean Inversion
Boolean expressions can be inverted using the !
operator
!true; // false
!false; // true
// Simplifies to !(false)
!(5 < 2); // true
// Simplifies to !(false || true), which is !(true)
!(5 < 2 || 10 > 5); // false
Boolean Implicit Conversion
Many types, including numeric types like int
and float
can be implicitly cast to booleans. Numeric values that are equal to 0
are considered false
, whilst any non-zero number is considered true
. For example:
bool MyBool { 0 }; // false
bool MyBool { 1 }; // true
Similarly, the opposite is true, although less useful. Boolean true
is implicitly cast to numeric 1
, whilst false
is cast to 0
int MyInt { true }; // 1
float MyFloat { false }; // 0.f
Summary
In this lesson, we took a tour of the fundamental building blocks of C++: variables, primitive data types, and operators. We learned how to declare and initialize variables, work with the built-in types, and perform operations on them. Key takeaways:
- C++ is a statically-typed language, meaning we must declare the type of a variable when we create it
- The basic built-in types are
bool
,int
,float
, anddouble
- We can initialize variables using braced initialization with the
{
and}
syntax - The
auto
keyword can be used for type deduction, but should be used sparingly for clarity - C++ provides arithmetic, comparison, and logical operators that work as expected from other languages
- Integer and floating-point division work differently - integer division returns the quotient, while floating-point division returns a precise result
- We can use explicit casts like
static_cast
when we need to convert between types
Introduction to Functions
Learn the basics of writing and using functions in C++, including syntax, parameters, return types, and scope rules.
Comments