Skip to main content
PProfileMatch

C++ Variables and Data Types

ProgrammingLesson 2 of 65 min read

What you'll learn

  • Declare and initialise variables with int, double, char, bool and std::string
  • Check type sizes with sizeof and know that sizes depend on the platform
  • Use auto, const and brace initialisation appropriately
  • Convert between types with static_cast and avoid integer-division traps

On this page

  1. Declaring and initialising variables
  2. The core types
  3. Finding sizes with sizeof
  4. auto, const and casting
  5. Common mistakes
  6. How this shows up in interviews and real projects

Every value in a C++ program has a type that decides how many bytes it occupies and what you can do with it. Pick the wrong type and a price loses its decimals, a counter wraps around, or a comparison quietly does something you did not intend. This lesson covers the types you will use every day and the habits that keep them safe.

Declaring and initialising variables

A declaration gives the type, then the name, then optionally a value: int age = 29;. C++ also supports brace initialisation, int age{29};, which refuses conversions that would lose information. That makes it a good default habit. Unlike Java, a local variable that you do not initialise is not set to zero; it holds whatever garbage was in that memory, and reading it is a bug.

The core types

The fundamental types are small and map closely to hardware. The sizes below are the usual ones on modern 64-bit desktop systems; the C++ standard only guarantees minimums and that sizeof(char) is 1, so use sizeof when it matters.

TypeTypical sizeHoldsExample
char1 byteA single character in single quoteschar grade = 'A';
bool1 bytetrue or falsebool inStock = true;
int4 bytesWhole numbers, roughly -2.1 billion to 2.1 billionint age = 29;
long long8 bytesVery large whole numberslong long people = 8000000000LL;
float4 bytesDecimals, about 7 significant digitsfloat rating = 4.5f;
double8 bytesDecimals, about 15 significant digitsdouble price = 499.99;
std::stringVariesText of any length (a class, not a primitive)string name = "Priya";
types.cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    int age = 29;
    double price = 499.99;
    char grade = 'A';
    bool inStock = true;
    string name = "Priya";

    cout << name << " is " << age << endl;
    cout << "Price: " << price << endl;
    cout << "Grade: " << grade << endl;
    cout << "In stock: " << inStock << endl;
    cout << boolalpha << "In stock: " << inStock << endl;

    string last = "Sharma";
    string full = name + " " + last;
    cout << full << " has " << full.length() << " characters" << endl;
    cout << full.substr(0, 5) << endl;
    cout << (name == "Priya") << endl;
    return 0;
}

Output

Priya is 29
Price: 499.99
Grade: A
In stock: 1
In stock: true
Priya Sharma has 12 characters
Priya
true

Two things to notice. A bool prints as 1 or 0 until you switch on boolalpha, and that setting is sticky for the rest of the stream. And std::string is far friendlier than Java strings in one way: == compares the text, and strings are mutable, so you can change them in place. Prefer std::string over old C-style char arrays for all text.

Finding sizes with sizeof

sizeof tells you how many bytes a type or variable occupies on the machine you are compiling for. It is evaluated at compile time. This is a useful way to confirm your assumptions instead of guessing.

sizes.cpp
#include <iostream>
using namespace std;

int main() {
    cout << "char: " << sizeof(char) << "\n";
    cout << "bool: " << sizeof(bool) << "\n";
    cout << "int: " << sizeof(int) << "\n";
    cout << "float: " << sizeof(float) << "\n";
    cout << "double: " << sizeof(double) << "\n";
    cout << "long long: " << sizeof(long long) << "\n";
    return 0;
}

Output

char: 1
bool: 1
int: 4
float: 4
double: 8
long long: 8

That output is typical for a 64-bit desktop system. Your machine may differ for anything except char, which is always 1.

auto, const and casting

auto asks the compiler to deduce the type from the initialiser, so auto items = 3; is an int and auto price = 250.0; is a double. It shines with long types such as iterators and is fine for obvious cases, but do not use it where it hides what a value is. const marks a value that cannot change after initialisation. Use it generously: it documents intent and lets the compiler catch accidental writes.

When you convert between types on purpose, use static_cast<type>(value). It is more visible and searchable than the old C-style (type)value. The program below shows the integer-division trap, truncation, character arithmetic and why 0.1 + 0.2 is not quite 0.3.

casting.cpp
#include <iomanip>
#include <iostream>
using namespace std;

int main() {
    const double TAX_RATE = 0.18;
    int total = 7;
    int count = 2;
    cout << total / count << endl;
    cout << static_cast<double>(total) / count << endl;

    auto price = 250.0;
    auto items = 3;
    auto bill = price * items * (1 + TAX_RATE);
    cout << bill << endl;

    cout << static_cast<int>(19.99) << endl;
    cout << 'A' + 1 << endl;
    cout << static_cast<char>('A' + 1) << endl;

    cout << 0.1 + 0.2 << endl;
    cout << setprecision(17) << 0.1 + 0.2 << endl;
    return 0;
}

Output

3
3.5
885
19
66
B
0.3
0.30000000000000004

7 / 2 is 3 because both operands are ints, so C++ performs integer division. Casting just one operand to double fixes it. Casting 19.99 to int truncates toward zero rather than rounding. 'A' + 1 is 66 because arithmetic promotes char to int, so you cast back to see B. Finally, cout shows only 6 significant digits by default, which hides the tiny binary rounding error until you ask for 17 digits. Never compare doubles for exact equality, and avoid them for money.

Common mistakes

  • Reading an uninitialised variable. int total; cout << total; compiles, but the value is garbage. With -Wall you may see warning: 'total' is used uninitialized.
  • Narrowing in brace initialisation. int x{3.5}; fails with error: narrowing conversion of '3.5' from 'double' to 'int'. With =, int x = 3.5; compiles and silently truncates to 3.
  • Integer division. double avg = sum / count; with two ints still divides as integers, then converts. Cast one side first.
  • Forgetting `#include <string>`. Depending on the compiler you get error: 'string' was not declared in this scope or 'string' does not name a type.
  • Single quotes versus double quotes. char c = "A"; fails with error: invalid conversion from 'const char*' to 'char'. A char uses single quotes and a string uses double.
  • Comparing doubles with `==`. 0.1 + 0.2 == 0.3 is false. Compare with a small tolerance, such as abs(a - b) < 1e-9.

How this shows up in interviews and real projects

Expect questions on integer overflow, the difference between const and constants defined with #define, what auto does, and why sizeof(int) is not always 4. In real C++ code, reaching for the right type is also a performance and correctness decision: fixed-width integers for file formats and networking, std::size_t for sizes, and const everywhere it applies. Next up is C++ If-Else, Switch and Loops.

Try it yourself

Write a program that stores a student's three subject marks as ints, computes the average as a double without losing the decimal part, and prints it. Declare the pass mark as a const int and print whether the student passed using boolalpha.

Show a hint

Sum the marks first, then use static_cast<double>(sum) / 3. Compare the average with your const pass mark.

Key takeaways

  • Use int, double, char, bool and std::string for most work, and long long when numbers get large.
  • Local variables are not zero-initialised, so always give them a value.
  • Type sizes depend on the platform; confirm with sizeof and use fixed-width types when exact size matters.
  • Use static_cast for deliberate conversions, const for values that must not change, and auto when the type is obvious.
  • Integer division truncates, doubles carry tiny rounding errors, and signed overflow is undefined behavior.

Test yourself

A trick from this lesson's ride: A fresh local is a room nobody cleaned: old junk is still inside. Four more tricks like it wait along the route, each followed by a question.

Ride this lesson

Frequently asked questions

What are the basic data types in C++?

The basic types are int, double and float for numbers, char for single characters and bool for true or false. Text is normally stored in std::string, which is a library class rather than a primitive type.

What is the difference between int and long long in C++?

int is usually 4 bytes and holds values up to about 2.1 billion, while long long is at least 64 bits and holds vastly larger numbers. Use long long when values such as totals, IDs or factorials might exceed the int range.

What does auto do in C++?

auto makes the compiler deduce a variable's type from its initial value, so auto x = 5; is an int. The variable is still statically typed, and you must give it an initialiser. It is especially useful for long types such as iterators.