Step 1 of 8 · Reading · ~3 min
Learn
Getting Started
Variables and Types
In C++ every variable has a type fixed when you declare it, and that type decides which values fit and how arithmetic on it behaves. By the end of this lesson you can pick an integer type that is wide enough, initialize it safely, and spot the overflow that a too-narrow type causes.
Declaring and initializing
A declaration names a variable and gives it a type. An initializer gives it its first value:
int lives = 3; // copy initialization
int level{7}; // brace initialization, the modern default
double speed = 2.5; // 64-bit floating point
bool paused = false; // true or false
char grade = 'B'; // one character, single quotes
auto score = 120; // auto: the compiler deduces int from 120
Brace initialization refuses to lose information: int level{7.9}; is a compile error, while int level = 7.9; quietly stores 7.
Always give a local variable a value. int hits; followed by std::cout << hits; is undefined behavior: C++ does not zero local variables, so the program may print 0, 32767, or anything else, and may look fine on your machine and fail on the grader. int hits{}; gives it 0.
Integer types have a range
| type | typical size | range |
|---|---|---|
int | 32 bits | -2147483648 to 2147483647 |
long long | 64 bits | about plus or minus 9.2 * 10^18 |
unsigned int | 32 bits | 0 to 4294967295 |
A result that does not fit is an overflow. For signed types it is undefined behavior; on g++ it usually wraps around to a wrong, often negative, number.
The trap: the type of an expression
Count the seconds in 30000 days. 30000 * 86400 is 2592000000, larger than the biggest int:
int days = 30000;
long long wrong = days * 86400;
long long right = static_cast<long long>(days) * 86400;
std::cout << wrong << "\n" << right << "\n";
Output on g++:
-1702967296
2592000000
wrong is a long long, yet it is wrong. The multiplication days * 86400 has two int operands, so it is computed as an int and overflows first; only the already-broken result is then widened into wrong. The type on the left of = does not change how the right side is computed.
Two fixes, both deciding the type before the arithmetic runs:
- convert one operand:
static_cast<long long>(days)makes the whole productlong long; - or declare the inputs wide from the start, e.g.
long long days = 30000;, so every expression using them is already 64-bit.
static_cast<T>(value) is the explicit C++ conversion. Prefer it to the C-style (long long)days: it does exactly one checked kind of conversion and is easy to search for.
std::cin >> reads into whatever type the variable has, so long long seconds; std::cin >> seconds; reads a 64-bit number with no extra work.
Common mistakes
- Leaving the result as
int. 2147483647 plus 1 prints -2147483648 instead of 2147483648. - Widening only the destination. A
long longon the left of=still receives an overflowedintexpression, so a large input prints the same wrong negative number as above. - Subtracting in the wrong order.
b - ainstead ofa - bflips the sign: for 1000 and 2500 the answer is -1500, not 1500. - Reading an uninitialized variable. Undefined behavior; it can pass one run and fail the next.
Your exercise
Read two integers and print their sum and their difference. The starter reads the numbers and prints two int variables; your job is choosing types so that both results are right even when they fall outside the int range. The mistake to avoid is widening only the variable that stores the result.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…