--- C++ Types • C++ Cabinet

C++ Types

  • C++ guarantees minimum sizes, not exact sizes. Actual size depends on platform (but on modern 64-bit systems there are common conventions).

Integer Types

  • Integer types store WHOLE numbers.
  • Whole numbers are defined as those that you can write without a fractional component.

short int (or just short)

  • Minimum size: 16 bits
  • Typical size (modern systems): 16 bits
  • Range (signed): −32,768 to 32,767
  • Range (unsigned): 0 to 65,535
  • Use when:
    • You explicitly want a smaller integer
    • Memory size matters (embedded, packed structs)

int

  • Minimum size: 16 bits
  • Typical size (modern systems): 32 bits
  • Range (signed, 32-bit): −2,147,483,648 to 2,147,483,647
  • Range (unsigned, 32-bit): 0 to 4,294,967,295
  • Use when:
    • You want the “default integer”
    • Performance matters (this is usually the CPU’s natural size)
    • In real-world modern C++, int is usually 32-bit and is the standard general-purpose integer.

long int (or long)

  • Minimum size: 32 bits
  • Typical size:
  • Windows (64-bit): 32 bits
  • Linux/macOS (64-bit): 64 bits
  • This is where portability bites.
  • Range depends on platform. Because long changes size depending on OS, it’s less predictable.

long long int (or long long)

  • Minimum size: 64 bits
  • Typical size: 64 bits everywhere
  • Range (signed): ~ ±9.22 quintillion
  • Range (unsigned): 0 to ~18.44 quintillion
  • Use when:
    • You explicitly need 64-bit integers
    • File sizes, large counters, hashing, etc.

Signed vs Unsigned Ints

Signed (default)

  • e.g. int x = -5;
  • Can represent negative and positive values
  • Uses one bit for sign (two’s complement representation)
  • Most arithmetic is designed assuming signed

Unsigned

  • e.g. unsigned int x = 5;

  • Only non-negative values

  • Entire bit width used for magnitude

  • Range doubles on positive side

  • Example (32-bit):

    • Signed max: 2.1 billion
    • Unsigned max: 4.2 billion
  • Integer literals can contain any number of single quotes (’) for readability - the compiler ignores them completely.

  • 1000000 and 1’000’000 are both integer literals equal to 1 million.

Floating-Point Types

  • Floating-point types store approximations of real numbers.
  • These are defined as any number that has a decimal point and a fractional part - e.g. 0.333 or 98.6
  • You cannot store a true arbitrary real number in computer memory, but you can store an approximation.
  • For example, imagne trying to store Pi in memory - you couldn’t possibly store an infinitely long number in finite computer memory.
  • Floating-point types take up a finite amount of memory, this is the type’s PRECISION:
    • float - single precision
    • double - double precision
    • long double - extended precision
  • On major desktop OSes, float level has 4 bytes of precision, double and long double have 8 bytes of precision, usually.
  • If you’re not doing scientific computing, you won’t need to worry about the finer points here.
  • Generally, just use a double and use %g to print them.

Character Types

  • Character types store human language data. There are six chatacter types:
    • char16_t - Used for 2-byte character sets (Example: UTF-16);
    • char32_t - Used for 4-byte character sets (Example: UTF-32);
    • signed char - same as char but guaranteed to be signed;
    • unsigned char - same as char but guaranteed to be unsigned;
    • wchar_t - Large enough to contain the largest chatacter of the implementation’s locale (Example: Unicode)
  • A character literal is a single, constant character, single quotation marks (”) surround all characters.
  • If the character is any type but char, you need a prefix:
    • L is for wchar_t,
    • U for char32_t,
    • u for char16_t.

Escape Sequences

  • These don’t display on the screen, they force cursor movements amongst other things.
  • These are reserved characters:
    • \n - newline
    • \t - tab (horizontal)
    • \v - tab (vertical)
    • \b - backspace
    • \r - carriage return
    • \f - form feed
    • \a - alert
    • \ - backslash
    • ? or ? - question mark
    • ’ - single quote
    • ” - double quote
    • \0 - Null character

Boolean Types

  • Boolean types have two states: true and false.
  • The sole boolean type is bool.
  • Bool and int convert easily - True state converts to 1, false state converts to 0.
  • There is no format specifier for bool, but you can use the int format specifier %d within printf.
  • You would just get it to yield a 1 for True and 0 for False. See types.cpp for an example.

Comparison Operators

  • Operators are functions that perform computations on operands.
  • Operands are just objects.
  • Comparison operators take two arguments and return a bool - that’s how we use them to build conditional (if x, then y) logic.
  • Your available comparison operators are:
    • == (equality)
    • != (inequality)
    • (greater than)

    • < (less than)
    • = (greater than or equal to)

    • <= (less than or equal to)
  • Each comparison produces a Boolean result.
  • Printf prints the Boolean as an int.

Logical Operators

  • Logical operators evaluate Boolean logic on bool types.
  • You characterize operators by how many operands they take.
  • UNARY operators take a single operand, BINARY operators take two, TERNARY operators take three, and so on.
  • UNARY - Negation operator - (!) - Takes a single operand and returns the opposite.
    • !true yields false, !false yields true.
  • BINARY - AND and OR - && and || - AND returns true only if BOTH operands are true. OR returns true if EITHER or BOTH operands are true.
  • TERNARY/Conditional operator – ?: – Takes three operands.
    • Syntax: condition ? expression_if_true : expression_if_false
    • Evaluates the first operand, the condition first.
    • If true → evaluates and returns the second operand.
    • If false → evaluates and returns the third operand.
    • Only one of the two result expressions is evaluated.

Size_t

  • Available in the to encode the size of objects
  • The size_t objects guarantee that their maximum values are sufficient to represent the maximum size in bytes of ALL objects.
  • This means a size_t could be 2 BYTES or 200 BYTES depending on implementation!
  • The size_t type is identical functionally between the C and C++ version.
  • You may occasionally see std::size_t instead.
  • The unary operator sizeof() takes a type operand and returns the size in bytes of that type.
  • size_t printf format specifiers are %zd for decimal representation, %zx for hexidecimal.

Void

  • The void type has an empty set of values.
  • Because a void object cannot hold a value, C++ disallows void objects.
  • You use void in special situations, such as the return type for functions that don’t return any value.

Working examples

These are rendered from the source stored beside this drawer's notes.

#include <cstdio> // This program, an amalgam of the examples from C++ Crash Course, only uses printf, which comes from this library.

/* The goal of this function is to assign several integer variables of different integer literal types, 
and prints them with the appropriate format specifier, to serve as a reference. */
void integer_types(){
    unsigned short a = 0b10101010; // 0b prefix - Binary integer literal representation of the number 170 - C++ has this hardcoded into it.
    printf("%hu\n", a); // %hu is the printf format specifier for this type of unsigned int in binary.
    int b = 0123; // 0 prefix - Octal integer literal presentation of the number 83 - C++ has this hardcoded into it too.
    printf("%d\n", b); // %d is the printf format specifier for an integer like this.
    unsigned long long c = 0xFFFFFFFFFFFFFFFF; // 0x prefix - Hexadecimal integer literal presentation of the number 18446744073709551615 - C++ has this hardcoded into it, too.
    printf("%llu\n\n", c); // %llu is the printf format specifier for unsigned long long ints.

    return;
}

/*The goal of this function is to assign several floating point variables and
then print them with the appropriate format specifier, to server as a reference.*/
void floatingpoint_types(){
    double an = 6.0332409e23; // You can use scientific notation in literals. as long as you dont use any spaces between the base and exponential portions.
    printf("Avogadro's number: %le,  %lf, %lg \n", an, an , an); // Use %le for scientific notation, %lf for decimal representation, %lg auto-selects based on precision.
    float hp = 9.75; // Floats, when passed to printf get promoted to doubles.
    printf("Hogwarts' Platform: %e, %f, %g \n\n", hp, hp, hp); // As a general rule, use %g to print floating-point types.

    return;
}

/* The goal of this function is to assign seeral character-typed variables and print them. */
void char_types(){
    char x = 'M'; // Standard char literal type, you'll use this 99% of the time.
    wchar_t y = L'Z'; // utilizes L prefix due to wchar_t type.
    printf("Windows binaries start with %c%lc. \n\n", x, y);

    return;
}

/* The goal of this function is to assign bool variables and use the int format specifiers to print true and false values.*/
void bool_type(){
    bool b1 = true; // b1 is true
    bool b2 = false; // b2 is false
    printf("B1 is true if the number is 1: %d, B2 is false if the number is 0: %d\n\n", b1, b2);

    return;
}


/* The goal of this function is to utilize comparison operators to produce Booleans and show how they can be used to print True or False ints.*/
void comparison_ops(){
    printf("If you see a 1 at the end of a comaprison statement, it means the operator returned a Bool true.\n");
    printf("If you see a 0 at the end of a comaprison statement, it means the operator returned a Bool false.\n");
    printf("7 == 7: %d\n", 7 == 7);
    printf("7 != 7: %d\n", 7 != 7);
    printf("10 > 20: %d\n", 10 > 20);
    printf("10 >= 20: %d\n", 10 >= 20);
    printf("10 < 20: %d\n", 10 < 20);
    printf("20 <= 20: %d\n\n", 20 <= 20);

    return;
}

/*The goal of this function is to just demonstrate usage of the logical operators in context, 
and print them using the appropriate format specifiers.*/
void logical_ops() {
    printf("Logical operators return 1 for true and 0 for false.\n\n");

    // Unary: !
    printf("!true: %d\n", !true);
    printf("!false: %d\n\n", !false);

    // Binary: &&
    printf("true && true: %d\n", true && true);
    printf("true && false: %d\n", true && false);
    printf("false && false: %d\n\n", false && false);

    // Binary: ||
    printf("true || false: %d\n", true || false);
    printf("false || false: %d\n\n", false || false);

    // Using comparisons with logical operators
    printf("(7 == 7) && (10 < 20): %d\n", (7 == 7) && (10 < 20));
    printf("(7 != 7) || (10 > 20): %d\n\n", (7 != 7) || (10 > 20));

    // Ternary operator
    printf("Think of these as following this logic - if (5>3) is true, then print 100, if it's false print 200.\n");
    printf("(5 > 3) ? 100 : 200: %d\n", (5 > 3) ? 100 : 200);
    printf("(2 > 3) ? 100 : 200: %d\n", (2 > 3) ? 100 : 200);

    return;
}




int main(){
    integer_types();
    floatingpoint_types();
    char_types();
    bool_type();
    comparison_ops();
    logical_ops();
}