cpp

Variables And Data Types

04_Variables_And_Data_Types⚙️
/**
 * ============================================================
 * C++ VARIABLES AND DATA TYPES
 * ============================================================
 * 
 * This file covers all fundamental data types in C++:
 * - Primitive types (int, float, double, char, bool)
 * - Type modifiers (short, long, signed, unsigned)
 * - Size and range of types
 * - Type inference with auto
 * 
 * Compile: g++ -std=c++17 -Wall 01_data_types.cpp -o data_types
 * Run: ./data_types
 * 
 * ============================================================
 */

#include <iostream>
#include <iomanip>
#include <limits>     // For numeric_limits
#include <climits>    // For INT_MAX, INT_MIN, etc.
#include <cfloat>     // For FLT_MAX, DBL_MAX, etc.
#include <typeinfo>   // For typeid

using namespace std;

int main() {
    cout << "============================================" << endl;
    cout << "     C++ VARIABLES AND DATA TYPES" << endl;
    cout << "============================================" << endl << endl;

    // ========================================================
    // PART 1: INTEGER TYPES
    // ========================================================
    
    cout << "--- PART 1: INTEGER TYPES ---" << endl << endl;
    
    // Basic integer
    int regularInt = 42;
    
    // Short integers (at least 16 bits)
    short shortNum = 32767;
    short int shortInt = -32768;
    
    // Long integers (at least 32 bits)
    long longNum = 2147483647L;
    long int longInt = -2147483648L;
    
    // Long long integers (at least 64 bits, C++11)
    long long veryLongNum = 9223372036854775807LL;
    
    // Unsigned integers (only positive values)
    unsigned int unsignedNum = 4294967295U;
    unsigned short unsignedShort = 65535;
    unsigned long unsignedLong = 4294967295UL;
    
    cout << "int:           " << regularInt << " (size: " << sizeof(int) << " bytes)" << endl;
    cout << "short:         " << shortNum << " (size: " << sizeof(short) << " bytes)" << endl;
    cout << "long:          " << longNum << " (size: " << sizeof(long) << " bytes)" << endl;
    cout << "long long:     " << veryLongNum << " (size: " << sizeof(long long) << " bytes)" << endl;
    cout << "unsigned int:  " << unsignedNum << " (size: " << sizeof(unsigned int) << " bytes)" << endl;
    
    // Integer literals with different bases
    cout << "\nInteger Literals:" << endl;
    int decimal = 42;       // Base 10
    int octal = 052;        // Base 8 (starts with 0)
    int hex = 0x2A;         // Base 16 (starts with 0x)
    int binary = 0b101010;  // Base 2 (C++14, starts with 0b)
    
    cout << "Decimal 42:    " << decimal << endl;
    cout << "Octal 052:     " << octal << endl;
    cout << "Hex 0x2A:      " << hex << endl;
    cout << "Binary 0b101010: " << binary << endl;
    
    // Digit separators (C++14)
    int million = 1'000'000;  // Easier to read
    long long bigNum = 1'234'567'890'123LL;
    cout << "With separators: " << million << ", " << bigNum << endl;
    
    cout << endl;

    // ========================================================
    // PART 2: FLOATING POINT TYPES
    // ========================================================
    
    cout << "--- PART 2: FLOATING POINT TYPES ---" << endl << endl;
    
    float floatNum = 3.14159f;           // Single precision
    double doubleNum = 3.141592653589793; // Double precision  
    long double longDouble = 3.14159265358979323846L; // Extended precision
    
    cout << fixed << setprecision(15);
    cout << "float:       " << floatNum << " (size: " << sizeof(float) << " bytes)" << endl;
    cout << "double:      " << doubleNum << " (size: " << sizeof(double) << " bytes)" << endl;
    cout << "long double: " << longDouble << " (size: " << sizeof(long double) << " bytes)" << endl;
    
    // Scientific notation
    double scientific1 = 6.022e23;    // 6.022 × 10^23 (Avogadro's number)
    double scientific2 = 1.6e-19;     // 1.6 × 10^-19 (electron charge)
    
    cout << "\nScientific notation:" << endl;
    cout << scientific << setprecision(3);
    cout << "6.022e23:  " << scientific1 << endl;
    cout << "1.6e-19:   " << scientific2 << endl;
    
    // Precision issues
    cout << "\nPrecision warning:" << endl;
    cout << fixed << setprecision(20);
    float f = 0.1f;
    double d = 0.1;
    cout << "0.1 as float:  " << f << endl;
    cout << "0.1 as double: " << d << endl;
    cout << "(Neither is exactly 0.1!)" << endl;
    
    cout << defaultfloat << setprecision(6);
    cout << endl;

    // ========================================================
    // PART 3: CHARACTER TYPES
    // ========================================================
    
    cout << "--- PART 3: CHARACTER TYPES ---" << endl << endl;
    
    char letter = 'A';
    char digit = '5';
    char newline = '\n';
    char tab = '\t';
    
    cout << "char 'A':      " << letter << " (ASCII: " << static_cast<int>(letter) << ")" << endl;
    cout << "char '5':      " << digit << " (ASCII: " << static_cast<int>(digit) << ")" << endl;
    cout << "char size:     " << sizeof(char) << " byte" << endl;
    
    // Character is actually a small integer
    char c = 65;  // Same as 'A'
    cout << "char 65:       " << c << endl;
    
    // char arithmetic
    char next = letter + 1;  // 'B'
    cout << "'A' + 1:       " << next << endl;
    
    // Special characters
    cout << "\nEscape sequences:" << endl;
    cout << "Newline: \\n" << endl;
    cout << "Tab:\tafter tab" << endl;
    cout << "Quote: \"quoted\"" << endl;
    cout << "Backslash: \\" << endl;
    cout << "Bell: \\a (may beep)" << '\a' << endl;
    
    // Wide characters
    wchar_t wideChar = L'Ω';  // Unicode character
    cout << "\nWide char size: " << sizeof(wchar_t) << " bytes" << endl;
    
    // C++11 character types
    char16_t char16 = u'A';   // UTF-16
    char32_t char32 = U'A';   // UTF-32
    cout << "char16_t size: " << sizeof(char16_t) << " bytes" << endl;
    cout << "char32_t size: " << sizeof(char32_t) << " bytes" << endl;
    
    cout << endl;

    // ========================================================
    // PART 4: BOOLEAN TYPE
    // ========================================================
    
    cout << "--- PART 4: BOOLEAN TYPE ---" << endl << endl;
    
    bool isTrue = true;
    bool isFalse = false;
    
    cout << "true:  " << isTrue << " (with boolalpha: " << boolalpha << isTrue << ")" << noboolalpha << endl;
    cout << "false: " << isFalse << " (with boolalpha: " << boolalpha << isFalse << ")" << noboolalpha << endl;
    cout << "bool size: " << sizeof(bool) << " byte" << endl;
    
    // Boolean from expressions
    bool result1 = (5 > 3);    // true
    bool result2 = (5 == 3);   // false
    bool result3 = (5 != 3);   // true
    
    cout << "\n5 > 3:  " << boolalpha << result1 << endl;
    cout << "5 == 3: " << result2 << endl;
    cout << "5 != 3: " << result3 << noboolalpha << endl;
    
    // Non-zero is true, zero is false
    bool fromInt1 = 42;   // true
    bool fromInt2 = 0;    // false
    bool fromInt3 = -1;   // true
    
    cout << "\n42 as bool: " << boolalpha << fromInt1 << endl;
    cout << "0 as bool:  " << fromInt2 << endl;
    cout << "-1 as bool: " << fromInt3 << noboolalpha << endl;
    
    cout << endl;

    // ========================================================
    // PART 5: TYPE SIZES AND RANGES
    // ========================================================
    
    cout << "--- PART 5: TYPE SIZES AND RANGES ---" << endl << endl;
    
    cout << left << setw(20) << "Type" << setw(10) << "Size" << "Range" << endl;
    cout << string(70, '-') << endl;
    
    cout << setw(20) << "char" << setw(10) << sizeof(char) 
         << CHAR_MIN << " to " << CHAR_MAX << endl;
    
    cout << setw(20) << "unsigned char" << setw(10) << sizeof(unsigned char)
         << "0 to " << UCHAR_MAX << endl;
    
    cout << setw(20) << "short" << setw(10) << sizeof(short)
         << SHRT_MIN << " to " << SHRT_MAX << endl;
    
    cout << setw(20) << "unsigned short" << setw(10) << sizeof(unsigned short)
         << "0 to " << USHRT_MAX << endl;
    
    cout << setw(20) << "int" << setw(10) << sizeof(int)
         << INT_MIN << " to " << INT_MAX << endl;
    
    cout << setw(20) << "unsigned int" << setw(10) << sizeof(unsigned int)
         << "0 to " << UINT_MAX << endl;
    
    cout << setw(20) << "long" << setw(10) << sizeof(long)
         << LONG_MIN << " to " << LONG_MAX << endl;
    
    cout << setw(20) << "long long" << setw(10) << sizeof(long long)
         << LLONG_MIN << " to " << LLONG_MAX << endl;
    
    cout << setw(20) << "float" << setw(10) << sizeof(float)
         << FLT_MIN << " to " << FLT_MAX << endl;
    
    cout << setw(20) << "double" << setw(10) << sizeof(double)
         << DBL_MIN << " to " << DBL_MAX << endl;
    
    cout << endl;

    // ========================================================
    // PART 6: TYPE INFERENCE (auto)
    // ========================================================
    
    cout << "--- PART 6: TYPE INFERENCE (auto) ---" << endl << endl;
    
    auto autoInt = 42;           // int
    auto autoDouble = 3.14;      // double
    auto autoFloat = 3.14f;      // float
    auto autoChar = 'A';         // char
    auto autoBool = true;        // bool
    auto autoLong = 123456789L;  // long
    
    cout << "auto 42:        " << autoInt << " (type: " << typeid(autoInt).name() << ")" << endl;
    cout << "auto 3.14:      " << autoDouble << " (type: " << typeid(autoDouble).name() << ")" << endl;
    cout << "auto 3.14f:     " << autoFloat << " (type: " << typeid(autoFloat).name() << ")" << endl;
    cout << "auto 'A':       " << autoChar << " (type: " << typeid(autoChar).name() << ")" << endl;
    cout << "auto true:      " << boolalpha << autoBool << " (type: " << typeid(autoBool).name() << ")" << noboolalpha << endl;
    
    // decltype - deduce type from expression
    int x = 10;
    decltype(x) y = 20;  // y is int
    cout << "\ndecltype(x) y = 20: " << y << " (same type as x)" << endl;
    
    cout << endl;

    // ========================================================
    // PART 7: TYPE CONVERSIONS
    // ========================================================
    
    cout << "--- PART 7: TYPE CONVERSIONS ---" << endl << endl;
    
    // Implicit conversion (automatic)
    int intVal = 10;
    double doubleVal = intVal;  // int → double (safe)
    cout << "Implicit int to double: " << doubleVal << endl;
    
    // Narrowing conversion (may lose data)
    double pi = 3.14159;
    int truncated = pi;  // double → int (truncates)
    cout << "Implicit double to int: " << truncated << " (truncated from " << pi << ")" << endl;
    
    // Explicit conversion (casting)
    double value = 9.7;
    
    // C-style cast (avoid in modern C++)
    int cStyle = (int)value;
    
    // C++ static_cast (preferred)
    int staticCast = static_cast<int>(value);
    
    cout << "\nExplicit casts of 9.7:" << endl;
    cout << "C-style (int):      " << cStyle << endl;
    cout << "static_cast<int>:   " << staticCast << endl;
    
    // Casting between numeric types
    char charVal = static_cast<char>(65);  // int → char
    int backToInt = static_cast<int>('Z'); // char → int
    
    cout << "\nstatic_cast<char>(65): " << charVal << endl;
    cout << "static_cast<int>('Z'): " << backToInt << endl;
    
    cout << endl;

    // ========================================================
    // SUMMARY
    // ========================================================
    
    cout << "============================================" << endl;
    cout << "DATA TYPES SUMMARY:" << endl;
    cout << "============================================" << endl;
    cout << "INTEGERS:  int, short, long, long long" << endl;
    cout << "UNSIGNED:  unsigned int, unsigned long, etc." << endl;
    cout << "FLOATING:  float, double, long double" << endl;
    cout << "CHARACTER: char, wchar_t, char16_t, char32_t" << endl;
    cout << "BOOLEAN:   bool (true/false)" << endl;
    cout << "INFERENCE: auto, decltype" << endl;
    cout << "CASTING:   static_cast<type>(value)" << endl;
    cout << "============================================" << endl;

    return 0;
}

// ============================================================
// KEY POINTS:
// ============================================================
/*
 * 1. Choose the right type for your data
 * 2. int is the default for whole numbers
 * 3. double is the default for decimals
 * 4. Use unsigned when values can't be negative
 * 5. Be aware of overflow and precision limits
 * 6. Use auto for complex types, explicit types for clarity
 * 7. Prefer static_cast over C-style casts
 */
Variables And Data Types - C++ Tutorial | DeepML