cpp
Variables And Data Types
04_Variables_And_Data_Types⚙️cpp
/**
* ============================================================
* 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
*/