Variables & Data Types
A program works with data: a student's marks, the price of a phone, the name of a city. A variable is a named box in memory that holds one piece of data. In C++ every variable has a type, which decides what kind of value it can hold and how much memory it uses. The type is fixed when you create the variable and never changes.
In this lesson you will create variables, meet the basic types, let the compiler work out types with auto, and make values unchangeable with const and constexpr.
Declaring variables
To create a variable you write its type, its name and, almost always, a starting value.
#include <print>
int main() {
int age = 21;
double height = 1.68; // metres
char grade = 'A';
bool passed = true;
long long population = 1'428'000'000; // ' separates digits (C++14)
std::println("Age: {}", age);
std::println("Height: {} m", height);
std::println("Grade: {}", grade);
std::println("Passed: {}", passed);
std::println("Population: {}", population);
age = 22; // change the value later
std::println("Next year: {}", age);
}Age: 21 Height: 1.68 m Grade: A Passed: true Population: 1428000000 Next year: 22
Creating a variable is called declaring it, and giving it its first value is initialising it. Later you can assign a new value with =, but only a value of a suitable type. Variable names may contain letters, digits and underscores, must not start with a digit and are case-sensitive, so marks and Marks are different variables. The single quotes in 1'428'000'000 are only there to help humans read the number.
The basic types
| Type | Holds | Typical size | Example |
|---|---|---|---|
int | Whole numbers | 4 bytes | int runs = 104; |
long long | Large whole numbers | 8 bytes | long long phone = 9876543210; |
double | Decimal numbers (about 15 digits) | 8 bytes | double price = 1299.50; |
float | Decimal numbers (about 7 digits) | 4 bytes | float temp = 36.6f; |
char | One character | 1 byte | char section = 'B'; |
bool | true or false | 1 byte | bool is_member = false; |
std::size_t | Sizes and counts (never negative) | 8 bytes on 64-bit | std::size_t count = 3; |
Sizes are not fixed by the standard; the table shows what you get on normal 64-bit Windows, Linux and macOS computers. You can check with sizeof, and find the limits with std::numeric_limits from <limits>:
#include <limits>
#include <print>
int main() {
std::println("int uses {} bytes", sizeof(int));
std::println("Largest int: {}", std::numeric_limits<int>::max());
std::println("Largest long long: {}", std::numeric_limits<long long>::max());
}int uses 4 bytes Largest int: 2147483647 Largest long long: 9223372036854775807
A 10-digit mobile number does not fit in an int, which is why the table uses long long for it. Going past the largest value of a signed type is called overflow, and in C++ it is undefined behaviour: the program may print nonsense or crash. Use double for decimals, and float only when memory is very tight.
Arithmetic and integer division
The operators +, -, * and / work as in school maths, and % gives the remainder. There is one trap: when both sides of / are whole numbers, C++ does integer division and throws away the fractional part.
#include <print>
int main() {
int mangoes = 17;
int friends = 5;
std::println("Each friend gets {}", mangoes / friends);
std::println("Left over: {}", mangoes % friends);
std::println("Exact share: {}", static_cast<double>(mangoes) / friends);
std::println("Also exact: {}", 17.0 / 5);
}Each friend gets 3 Left over: 2 Exact share: 3.4 Also exact: 3.4
static_cast<double>(mangoes) converts the value to a double before dividing, so the division is done with decimals. If at least one side of / is a double, the result is a double. C++ also has shortcut operators: x += 5 means x = x + 5, and ++x adds one.
Brace initialisation
You can also initialise a variable with curly braces. The braces protect you from narrowing, a conversion that silently loses information.
int a = 9.99; // compiles (maybe with a warning): a becomes 9
int b{9.99}; // error: narrowing conversion from double to int
int c{}; // empty braces give zeroMany C++ programmers use braces for this safety. Both styles are common; the important rule is to always initialise. A local variable declared without a value, such as int total;, holds garbage, and reading it is undefined behaviour.
auto: let the compiler work out the type
With auto, the compiler deduces the type from the starting value. It saves typing and avoids mistakes when type names are long.
#include <print>
constexpr double gst_rate = 0.18; // fixed at compile time
constexpr int square(int n) { return n * n; }
int main() {
auto price = 1299; // int
auto discount = 0.10; // double
const auto final_price = price - price * discount; // double
constexpr int floor_area = square(12); // the compiler works this out
std::println("Final price: Rs. {}", final_price);
std::println("With GST: Rs. {:.2f}", final_price * (1 + gst_rate));
std::println("Area: {} sq ft", floor_area);
}Final price: Rs. 1169.1 With GST: Rs. 1379.54 Area: 144 sq ft
price * discount mixes an int and a double, so the result is a double. The format {:.2f} prints exactly two decimal places.
const and constexpr
constmeans "this value never changes after it is set". The value may come from user input or a calculation at run time. Trying to assign to it later is a compile error.constexprmeans "this value is known at compile time". The compiler calculates it while building the program, so it costs nothing when the program runs. Aconstexprfunction such assquarecan run at compile time when its arguments are constants.
Use constexpr for fixed facts such as tax rates and limits, const for values that are calculated once and then stay the same, and plain variables only for values that really change.
Common mistakes
- Using a variable before giving it a value.
int total; total += 5;reads garbage. Writeint total = 0;. - Expecting decimals from integer division.
5 / 2is2. Make one side adouble. - Using
intfor very large numbers. Phone numbers, populations and money in paise can exceed 2,147,483,647; uselong long. - Overusing
auto.auto x = 5;is clear, but when the type is not obvious from the right-hand side, writing the type helps readers.
Key points
- Every C++ variable has a fixed type such as
int,double,char,boolorlong long. - Always initialise variables; brace initialisation
int x{5};also blocks narrowing conversions. - Dividing two integers drops the fraction; use
static_cast<double>or a decimal literal. autolets the compiler deduce the type from the initial value.constvalues cannot change;constexprvalues and functions are worked out at compile time.
Exercise
A school canteen sells samosas at Rs. 15 each. Write a program with a constexpr price, an int number of samosas bought (7), and an int amount paid (200). Print the total cost, the change returned, and the average cost per samosa when Kabir gets 2 free samosas with his order (total cost divided by 9), shown with two decimal places.
Show solution
#include <print>
constexpr int samosa_price = 15;
int main() {
int bought = 7;
int paid = 200;
int total = bought * samosa_price;
int change = paid - total;
double average = static_cast<double>(total) / (bought + 2);
std::println("Total: Rs. {}", total);
std::println("Change: Rs. {}", change);
std::println("Average per samosa: Rs. {:.2f}", average);
}Total: Rs. 105 Change: Rs. 95 Average per samosa: Rs. 11.67
Without static_cast<double>, 105 / 9 would be integer division and give 11.
Quick Quiz
1. What does std::println("{}", 9 / 4); print?
Both values are integers, so the fractional part is dropped.
2. Which line fails to compile?
Brace initialisation does not allow narrowing from double to int.
3. What type does auto x = 2.5; give x?
A decimal literal without a suffix is a double, so auto deduces double.
4. What is special about a constexpr variable?
constexpr values are computed by the compiler, so they cost nothing at run time.
Learn C++ with a mentor
Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
