Programming languages have several primitive data types to store and represent data. Languages can be divided into several categories of languages:

  • Strongly/weakly typed
    • Weakly-typed languages convert between unrelated types implicitly.
    • Strongly-typed languages don’t allow implicit conversions.
  • Statically/dynamically typed
    • Statically-typed languages do type checking (verifying/enforcing constraints) at compile-time.
    • Dynamically-typed languages do this at runtime.

Common types

A brief list of common types in programming languages:

  • Integers
    • int, 32 bits
    • short, 16 bits
    • long, 32 bits
    • long long, 64 bits
  • Floating-point number
    • float, 32 bits, 7 digit precision
    • double, 64 bits, 15 digit precision (“double precision”)
    • long double, 19 digit precision
  • Text
    • char, 8 bits, in single quotes
    • string, for a size-varying string, in double quotes
  • Boolean values, bool (true, false)
  • And the void type

Note that the exact bit/byte length for a type will vary from machine to machine. Often some types are defined such that we can use a certain bit length, i.e., int8_t (or i8) for an 8-int signed integer.

Type annotations

In most languages (sans JavaScript), we either have the option or obligation to annotate a variable with a type. This should be instinct, especially in languages like Python.

If a value can be more than one type, we specify this with a union type, where we have a vertical pipe | separate the types in the annotation. This behaviour’s supported in Python and TypeScript. C, C++, and Rust support union types via a different mechanism.

Inferred types

In some programming languages, there are keywords (or a lack thereof) that allow the compiler or interpreter to deduce the correct type given an assignment expression. This usually doesn’t make it dynamically typed or easily switchable (if we’re using a statically typed language), but it does permit us to make our code a little cleaner.

In C-style languages, it also makes range-based for loops easier, i.e., for (auto i = 0; ...) or for (auto i: container_t).

Language support:

  • In C++11 onwards, the auto type does this.
  • In Java 10 onwards, the var type does this.

Variant types

A composite data type is constructed with multiple primitive data types (listed above). In C/C++/Rust, composite types are implemented with the struct keyword.