Data Types Basics
Lesson outline
Understanding Data Types
In C++, every object has a type that determines the values it can hold, how much memory it uses (implementation-defined), and which operations are valid.
Choosing the right type affects performance, correctness, and clarity (e.g., avoiding overflow or precision loss).
Fundamental Type Families
C++ fundamental (built-in) types include:
- Arithmetic types:
- Integral:
bool,char/signed char/unsigned char,wchar_t,char8_t(C++20),char16_t,char32_t,short,int,long,long longand their unsigned variants - Floating-point:
float,double,long double void(no value),std::nullptr_t(the type ofnullptr).
Library types like std::string, std::vector, etc., are not fundamental - they are class types provided by the standard library.
Fundamental Types - Quick Demo
This snippet declares one of each common category and prints them. Note: sizes and ranges are implementation-defined; query them at runtime.
Fixed-Width Integer Types ()
When you need exact widths for I/O, binary formats, or portability, prefer fixed-width types from (e.g., std::int32_t, std::uint64_t). Use std::size_t for sizes and indexes.
Character & Boolean Nuances
charis distinct fromsigned charandunsigned char; the signedness of plaincharis implementation-defined.- Wide/Unicode characters:
wchar_t,char16_t, andchar32_trepresent wider code units (encoding/size is implementation-defined). booloutputs as1/0by default; usestd::boolalphato printtrue/false.
Floating-Point Types
float (typically ~7 decimal digits), double (~15), and long double (implementation-defined, often >= double) trade precision for memory and speed. Avoid testing floating-point values with ==; compare within a tolerance.
Literal Suffixes & Initialization
Use literal suffixes to control types: 1.0f (float), 1.0 (double), 1.0L (long double), 42u (unsigned), 42LL (long long). Prefer brace initialization to avoid narrowing.
Best Practices
- Use
std::size_tfor sizes/indices andfixed-width types for serialized/binary data. - Do not assume exact sizes of fundamental types; use
sizeofandwhen necessary. - Prefer
doublefor general-purpose floating-point unless memory/perf dictates otherwise. - Be careful with signed/unsigned mixing and integer overflow (signed overflow is undefined behavior).
- Use clear, self-documenting types that match your domain (e.g.,
std::chronodurations for time).