Literals and Type Conversion

Integer, Floating-Point, Character, and String Literals

Integer, floating point, character, and string literals are fixed values written directly in source code. They are not variables. They are the raw numbers, letters, and text that the compiler turns into concrete data when it encounters them.

Each kind of literal has its own accepted forms, prefixes, suffixes, and rules. These details determine the type and value that the compiler gives to the literal.

An integer literal is a whole number written directly in the code.

The most common form is decimal. The compiler treats a plain decimal integer literal as an int when its value fits. If the value is too large for an int, the compiler selects a wider signed integer type that can represent it, such as long or long long.

42
1000
-7

Integer literals may also be written using other number bases.

A leading 0 begins an octal literal, which uses base 8. A value such as 0755 represents decimal 493. Digits 8 and 9 are not valid in an octal literal, so accidentally adding a leading zero can cause a compilation error.

The prefix 0x or 0X begins a hexadecimal literal, which uses base 16. For example, 0xFF represents decimal 255. Hexadecimal literals are especially useful when working with bit patterns or values related to hardware.

The prefix 0b or 0B, available since C++14, begins a binary literal. A value such as 0b1010 represents decimal 10. Binary literals make the individual bits of a value easier to see.

int decimal{42};
// A leading zero makes this an octal literal
int octal{0755};
int hexadecimal{0xFF};
int binary{0b1010};

A suffix may be added to control the type of an integer literal.

The suffix u or U makes the literal unsigned. The suffix l or L gives it type long, while ll or LL gives it type long long.

Suffixes may be combined. For example, 42ull has type unsigned long long.

unsigned int unsigned_value{42u};
long long_value{42L};
long long long_long_value{42LL};
unsigned long long large_value{42ull};

The order and capitalization of the suffix letters generally do not change their meaning, but using a consistent style makes the code easier to read.

Writing a large integer without an appropriate suffix can cause the compiler to select a different type than the programmer expected. Adding a suffix makes the intended type visible in the source code.

Floating point literals represent numbers that may contain a fractional part.

A literal that contains a decimal point or an exponent has type double by default. This gives it more precision than float unless another type is explicitly requested.

3.14
0.5
.25
2.

Scientific notation may be used to represent very large or very small values. The letter e or E separates the main value from its exponent. The exponent must be an integer.

1.23e4
6.02E23
1e-3

The suffix f or F gives a floating point literal type float. Without this suffix, the literal is a double, even when it is later assigned to a float variable.

The suffix l or L gives the literal type long double.

float first{3.14f};
double second{3.14};
long double third{3.14L};

Suffixes can also be used with scientific notation. A value such as 1.5e2f is a float representing 150.

The presence of a decimal point can change the type of a literal. The literal 5 is an int, while 5. is a double. This distinction affects expressions such as division, where integer and floating point arithmetic produce different results.

// Integer division discards the fractional part
int integer_result{5 / 2};
double floating_result{5.0 / 2.0};

A character literal is a single character enclosed in single quotes.

'A'
'7'
' '

An ordinary character literal has type char. Its stored value is the numeric code used by the implementation for that character, commonly based on ASCII or a compatible character encoding.

Escape sequences allow characters to be written when they are difficult to type directly or would otherwise interfere with the syntax of the literal.

Common escape sequences include '\n' for a newline, '\t' for a horizontal tab, '\'' for a single quote, '\\' for a backslash, and '\0' for the null character.

// Use the newline escape sequence inside this literal
char newline{'\n'};
char tab{'\t'};
char quote{'\''};
char backslash{'\\'};
char null_character{'\0'};

Characters can also be written using hexadecimal or octal escape sequences.

// Escape the backslash so it becomes part of the literal
char hexadecimal_character{'\x41'};
char octal_character{'\101'};

A character literal containing more than one character, such as 'AB', is permitted, but its value is implementation defined. Multi character literals are best avoided because their meaning is not portable.

Wide and Unicode character literals are also available. These include forms such as L'A', u'A', and U'A'. Ordinary character literals remain the most common choice when wider character support is not required.

A string literal is a sequence of characters enclosed in double quotes.

"hello"
"line one\nline two"

An ordinary string literal has the type array of const char. The compiler automatically places a null character, '\0', after the final visible character. The array therefore contains one more element than the number of characters written between the quotes.

String literals written next to one another are combined by the compiler into a single string. This makes it possible to divide a long piece of text across several source lines.

"hello "
"world"

Escape sequences work inside string literals in the same way that they work inside character literals. Common examples include \n, \t, \", and \\.

Raw string literals, available since C++11, allow text containing backslashes and quotation marks to be written without escaping every special character.

// Use a raw string so backslashes do not need escaping
R"(C:\Users\name\file.txt)"

A raw string begins with the R prefix and places the text inside parentheses. A custom delimiter may be used when the text itself contains the normal closing sequence.

String literals must be treated as read only. Attempting to modify their characters through a non const pointer results in undefined behavior.

Integer literals may use decimal, octal, hexadecimal, or binary notation, and their suffixes control the selected integer type.

Floating point literals use a decimal point or exponent and have type double unless a suffix requests float or long double.

Character literals contain a single character in single quotes, while string literals contain a sequence of characters in double quotes.

#include <iostream>

int main()
{
    int decimal{42};
    int hexadecimal{0x2A};
    int binary{0b101010};
    unsigned long long big{3000000000ull};

    double pi{3.14159};
    float almost_pi{3.14f};
    double avogadro{6.022e23};

    char letter{'A'};
    char newline{'\n'};
    char tab{'\t'};

    std::cout << "Decimal: " << decimal << '\n';
    std::cout << "Hexadecimal: " << hexadecimal << '\n';
    std::cout << "Binary: " << binary << '\n';
    std::cout << "Big: " << big << '\n';
    std::cout << "Pi: " << pi << '\n';
    std::cout << "Almost pi: " << almost_pi << '\n';
    std::cout << "Avogadro: " << avogadro << '\n';
    std::cout << "Letter: " << letter << '\n';
    std::cout << "Greeting: " << "Hello, literals!" << '\n';
    std::cout << "Path: " << R"(C:\temp\data.txt)" << '\n';

    std::cout << "Numeric value of 'A': "
              // Perform this conversion explicitly
              << static_cast<int>(letter)
              << '\n';
}

Prefixes, suffixes, and escape sequences quietly determine the type and exact value produced by a literal.

Exercise: Integer, Floating-Point, Character, and String LiteralsStarter code, hints and solutionOpenClose
Guided practiceBeginner · 10–15 min

Practice: Integer, Floating-Point, Character, and String Literals

Work through the mission, reveal hints only when needed, and compare your result with the model solution.

Your challenge

Change the greeting literal to Hello, C++ literals! and leave the numeric, character, and raw-string examples alone. Identify the exact changed output.

Mission checklist

  1. Run the starter as a baseline, then predict the change requested in Your challenge.
  2. Make that change in your editor; use the lesson-specific hints if you need help.
  3. Compile and run your answer, then compare with the worked solution and explain the result.

Starter program

This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.

#include <iostream>

int main()
{
    int decimal{42};
    int hexadecimal{0x2A};
    int binary{0b101010};
    unsigned long long big{3000000000ull};

    double pi{3.14159};
    float almost_pi{3.14f};
    double avogadro{6.022e23};

    char letter{'A'};
    char newline{'\n'};
    char tab{'\t'};

    std::cout << "Decimal: " << decimal << '\n';
    std::cout << "Hexadecimal: " << hexadecimal << '\n';
    std::cout << "Binary: " << binary << '\n';
    std::cout << "Big: " << big << '\n';
    std::cout << "Pi: " << pi << '\n';
    std::cout << "Almost pi: " << almost_pi << '\n';
    std::cout << "Avogadro: " << avogadro << '\n';
    std::cout << "Letter: " << letter << '\n';
    std::cout << "Greeting: " << "Hello, literals!" << '\n';
    std::cout << "Path: " << R"(C:\temp\data.txt)" << '\n';

    std::cout << "Numeric value of 'A': "
              // Perform this conversion explicitly
              << static_cast<int>(letter)
              << '\n';
}

Hints

Hint 1

Compare the spelling of 42, 0x2A, and 0b101010: they use different bases for the same integer. The stream still prints integers in decimal unless its base is changed.

Hint 2

For a text change, edit the greeting or the raw path literal. In R"(C:\temp\data.txt)", the backslashes are literal characters rather than escape sequences.

Worked solution

The greeting string is changed to Hello, C++ literals! A double-quoted literal contributes its characters to the output; the other numeric, character, and raw-string literals keep their original meanings.

#include <iostream>

int main()
{
    int decimal{42};
    int hexadecimal{0x2A};
    int binary{0b101010};
    unsigned long long big{3000000000ull};

    double pi{3.14159};
    float almost_pi{3.14f};
    double avogadro{6.022e23};

    char letter{'A'};
    char newline{'\n'};
    char tab{'\t'};

    std::cout << "Decimal: " << decimal << '\n';
    std::cout << "Hexadecimal: " << hexadecimal << '\n';
    std::cout << "Binary: " << binary << '\n';
    std::cout << "Big: " << big << '\n';
    std::cout << "Pi: " << pi << '\n';
    std::cout << "Almost pi: " << almost_pi << '\n';
    std::cout << "Avogadro: " << avogadro << '\n';
    std::cout << "Letter: " << letter << '\n';
    std::cout << "Greeting: " << "Hello, C++ literals!" << '\n';
    std::cout << "Path: " << R"(C:\temp\data.txt)" << '\n';

    std::cout << "Numeric value of 'A': "
              // Perform this conversion explicitly
              << static_cast<int>(letter)
              << '\n';
}

Example output

This is one tested C++20 run. Sizes, capacity, formatting, floating-point details, or extra container lifetime messages may differ by implementation; use the explanation to identify the guaranteed result.

Decimal: 42
Hexadecimal: 42
Binary: 42
Big: 3000000000
Pi: 3.14159
Almost pi: 3.14
Avogadro: 6.022e+23
Letter: A
Greeting: Hello, C++ literals!
Path: C:\temp\data.txt
Numeric value of 'A': 65

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.