C++ Programming

Introduction to C++

Programming Fundamentals

  • Computer programming: Creating instructions for computers.

  • Programs follow the Input-Process-Output (IPO) model:

    • Input: Data from files, keyboards, or networks.

    • Process: Computations on the input data.

    • Output: Results to screen or file.

  • Example C++ program:

    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "Hello, World!" << endl;
        return 0;
    }
    
    • #include <iostream>: Includes the iostream library for input/output operations.

    • using namespace std;: Uses names from the standard library without the std:: prefix.

    • main() function: Entry point of the program.

    • cout: Outputs text to the screen.

    • endl: Adds a newline character.

    • return 0;: Indicates successful execution.

Programming Basics

Essential Elements

  • Program: A sequence of instructions executed by a computer.

  • Algorithm: Step-by-step procedure for solving a problem.

  • Computational Thinking: Breaking down problems for computer execution.

  • Statements: Individual instructions ending with a semicolon (;).

  • Comments: Explanatory text ignored by the compiler.

    • Single-line comments: //

    • Multi-line comments: /* ... */

  • Whitespace: Spaces, tabs, and newlines for readability.

Input and Output

  • cout: Character output with the insertion operator (<<).

  • cin: Character input with the extraction operator (>>).

  • endl or \n: Creates a new line in the output.

  • Example:

    #include <iostream>
    using namespace std;
    
    int main() {
        int userAge;
        cout << "Please enter your age: ";
        cin >> userAge;
        cout << "You are " << userAge << " years old." << endl;
        return 0;
    }
    
  • Key concept: A program is a sequence of instructions for a computer, and computational thinking involves breaking down problems into steps a computer can execute.

Errors and Debugging

Types of Errors

  • Syntax Errors: Violations of language rules.

    • Example: Missing semicolons, unmatched brackets.

    • Detected during compilation.

  • Logic Errors (Bugs): Unexpected behavior despite successful compilation.

    • Example: Using < instead of <= in a condition.

    • Found during execution or testing.

  • Warnings: Potential issues flagged by the compiler.

    • Not severe enough to prevent compilation, but should be addressed.

Debugging Tips

  • Read error messages carefully.

  • Compile and test in small increments.

  • Use print statements to track variable values.

  • Comment out sections of code to isolate problems.

  • Example:

    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "This line is missing a semicolon"  // Error: missing semicolon
        cout << "This line will cause a compiler error." << endl;
        return 0;
    }
    

Computer Systems and C++ History

Basic Computer Architecture

  • Processor (CPU): Executes machine instructions.

  • Memory: Stores data and instructions.

  • Storage: Permanently holds files and programs.

  • Input/Output devices: Allow interaction with the computer.

C++ Language History

  • C: Developed in 1978 by Brian Kernighan and Dennis Ritchie at AT&T Bell Labs.

  • C++: Created by Bjarne Stroustrup in 1985 as an extension of C.

  • C++ added object-oriented features.

  • C++ remains popular for performance-critical applications.

Integrated Development Environment (IDE)

Components of an IDE

  • Text Editor: For writing code with syntax highlighting.

  • Compiler: Translates source code into executable programs.

  • Debugger: Helps find and fix errors.

  • Build Automation Tools: Manage the compilation process.

  • Popular C++ IDEs: Visual Studio, CLion, Code::Blocks, and Eclipse.

Variables and Assignments

Variables Basics

  • A variable is a named storage location in memory.

  • Holds a value of a specific type.

  • Variable Declaration: Specifies a name and a data type.

    • Example: int age;, double price;, char grade;, string name;

  • Variable Assignment: Assigns a value to a variable using the assignment operator (=).

    • Example: age = 25;, price = 19.99;, grade = 'A';, name = "John Smith";

  • Example:

    int score;  // Declaration
    score = 100;  // Assignment
    int level = 5;  // Declaration with initialization
    

Identifiers and Naming Conventions

Rules for Valid Identifiers

  • Must begin with a letter or underscore (_).

  • Can contain letters, digits, and underscores.

  • Cannot be a C++ keyword (like int, double, if, etc.).

  • Cannot contain spaces or special characters.

Naming Conventions

  • Lower Camel Case: First word lowercase, capital first letter of subsequent words.

    • Example: studentName, totalAmount

  • Snake Case: All lowercase with underscores separating words.

    • Example: student_name, total_amount

  • Use meaningful names that reflect the variable's purpose.

  • Avoid single-letter names except for simple counters.

Data Types

Fundamental Data Types

  • int: Integer (e.g., 42)

    • Typical Size: 4 bytes

    • Range: [-2,147,483,648, 2,147,483,647]

  • short: Short integer (e.g., 1000)

    • Typical Size: 2 bytes

    • Range: [-32,768, 32,767]

  • long: Long integer (e.g., 1000000L)

    • Typical Size: 4 bytes (same as int in some systems)

    • Range: Same as int

  • long long: Very long integer (e.g., 9000000000LL)

    • Typical Size: 8 bytes

    • Range: Approximately 9.2 * 10^{18}

  • float: Single-precision floating-point (e.g., 3.14159F)

    • Typical Size: 4 bytes

    • Range: 3.4 * 10^{38} (7 digits)

  • double: Double-precision floating-point (e.g., 3.14159265358979)

    • Typical Size: 8 bytes

    • Range: 1.7 * 10^{308} (15 digits)

  • char: Character (e.g., 'A', '7', '$')

    • Typical Size: 1 byte

    • Range: -128 to 127 or 0 to 255

  • bool: Boolean (e.g., true, false)

    • Typical Size: 1 byte

    • Values: true or false

  • Key Concepts

    • Variables must be declared before use

    • Variables can appear on both sides of an assignment.

    • Example: count = count + 1; increments the value of count.

    • Variable names are case-sensitive (myVar is different from myvar).

Type Modifiers

Unsigned Types

  • unsigned: Modifies integer types to represent non-negative values only.

    • Example: unsigned int positiveOnly = 100;, unsigned char byte = 255;

    • Doubles the positive range but eliminates negative values.

Constant Variables

  • const: Creates variables whose values cannot change after initialization.

    • Example: const double PI = 3.14159265358979;, const int MAX_STUDENTS = 30;

Arithmetic Expressions

Basic Arithmetic Operators

  • Addition: + (e.g., a + b)

  • Subtraction: - (e.g., a - b)

  • Multiplication: * (e.g., a * b)

  • Division: / (e.g., a / b)

  • Modulo (remainder): % (e.g., a % b)

Order of Operations (Precedence)

  1. Parentheses ()

  2. Unary operators +, - (as in -x)

  3. Multiplication *, Division /, Modulo %

  4. Addition +, Subtraction -

Integer Division and Modulo

  • Integer division truncates the result (removes any fractional part).

    • Example: int quotient = 7 / 3; (quotient is 2)

  • Modulo gives the remainder of a division.

    • Example: int remainder = 7 % 3; (remainder is 1)

  • To get a floating-point result, at least one operand must be a floating-point type.

    • Example: double result = 7.0 / 3; (result is 2.33333…)

Compound Assignment Operators

  • +=: a = a + b (e.g., a += 5)

  • -=: a = a - b (e.g., a -= 5)

  • *=: a = a * b (e.g., a *= 5)

  • /=: a = a / b (e.g., a /= 5)

  • %=: a = a % b (e.g., a %= 5)

Type Conversions

Implicit Conversions

  • The compiler automatically converts types in certain situations.

    • Example: int i = 10; double d = i; (i is converted to double)

    • Loses precision

Explicit Conversions (Casting)

  • Use explicit type casting when you want to control the conversion.

    • C-style cast (avoid in modern C++): int i = (int)3.99;

    • Modern C++ cast operators: int i2 = static_cast<int>(d);

    • The preferred C++ cast operator is static_cast<type>().

    • Example double d = 9.8; int i2 = static_cast<int>(d);

Mathematical Functions

C++ <cmath> Library

#include <cmath>
  • sqrt(x): Square root of x.

  • pow(x, y): x raised to power y.

  • abs(x) or fabs(x): Absolute value.

  • sin(x), cos(x), tan(x): Trigonometric functions.

  • exp(x): e raised to power x.

  • log(x): Natural logarithm of x.

  • log10(x): Base-10 logarithm of x.

double squareRoot = sqrt(25.0);  // 5.0
double power = pow(2.0, 3.0);  // 2^3 = 8.0
double absolute = fabs(-7.5);  // 7.5
double ceiling = ceil(3.2);  // 4.0 (rounds up)
double floor = floor(3.8);  // 3.0 (rounds down)
double roundedValue = round(3.5);  // 4.0 (rounds to nearest)

Character Operations

  • Characters are stored as numeric ASCII values, allowing arithmetic operations.

    • Example: char letter = 'A'; char nextLetter = letter + 1; (nextLetter is 'B')

<cctype> Library

#include <cctype>
  • Provides character testing and manipulation functions.

  • isalpha(c): True if c is a letter.

  • isdigit(c): True if c is a digit.

  • isspace(c): True if c is whitespace.

  • toupper(c): Converts c to uppercase.

  • tolower(c): Converts c to lowercase.

String Basics

<string> Library

#include <string>
using namespace std;
  • Strings represent sequences of characters.

  • string greeting = "Hello, World!";

  • string empty; (Empty string)

  • string name = "John";

  • string fullName = name + " Doe"; (String concatenation)

  • int length = fullName.size(); (or .length()) to get the string length

String Operations

  • str += " there"; (Append)

  • char firstChar = str[0]; (Access by index).

  • char lastChar = str.at(str.length() - 1);(Safe access using .at()).

  • string sub = str.substr(0, 5); (Substring from position 0, length 5).

  • size_t pos = str.find("there"); (Finds position where substring starts).

Random Numbers

<cstdlib> Library

#include <cstdlib>
#include <ctime>

// Seed the random number generator
srand(time(0));  // Use current time as seed

// Generate random integers
int randomNumber = rand();  // 0 to RAND_MAX
int diceRoll = (rand() % 6) + 1;  // 1 to 6
int randomRange = rand() % 101;  // 0 to 100
int rangeStart10 = 10 + (rand() % 91);  // 10 to 100

<random> Library

  • C++11 introduced the <random> library for better random numbers.

#include <random>
#include <ctime>

// Create a random number generator
std::mt19937 rng(time(0));  // Mersenne Twister with seed from current time

// Create distributions for different ranges
std::uniform_int_distribution<int> dice(1, 6);  // 1 to 6
std::uniform_real_distribution<double> unit(0.0, 1.0);  // 0.0 to 1.0

// Generate random numbers
int roll = dice(rng);  // Random dice roll
double probability = unit(rng);  // Random double between 0 and 1

Branches

Decision Making with if Statements

  • Simple if Statement

    if (condition) {
        // Code executed only if condition is true
    }
    
    int age = 20;
    if (age >= 18) {
        cout << "You are eligible to vote." << endl;
    }
    
  • if-else Statement

    if (condition) {
        // Code executed if condition is true
    } else {
        // Code executed if condition is false
    }
    
    int temperature = 15;
    if (temperature > 20) {
        cout << "It's warm outside." << endl;
    } else {
        cout << "It's cool outside." << endl;
    }
    
  • if-else if-else Statement

    if (condition1) {
        // Code executed if condition1 is true
    } else if (condition2) {
        // Code executed if condition1 is false and condition2 is true
    } else {
        // Code executed if all conditions are false
    }
    

Comparison Operators

  • ==: Equal to (e.g., a == b)

  • !=: Not equal to (e.g., a != b)

  • >: Greater than (e.g., a > b)

  • <: Less than (e.g., a < b)

  • >=: Greater than or equal to (e.g., a >= b)

  • <=: Less than or equal to (e.g., a <= b)

Logical Operators

  • &&: Logical AND (e.g., a && b)

  • ||: Logical OR (e.g., a || b)

  • !: Logical NOT (e.g., !a)

  • Short-circuit evaluation for && and ||.

Switch Statements

  • Alternative to multiple if-else statements when checking a single variable against multiple values.

    switch (expression) {
        case value1:
            // Code executed if expression equals value1
            break;
        case value2:
            // Code executed if expression equals value2
            break;
        // More cases...
        default:
            // Code executed if expression doesn't match any case
            break;
    }
    
    char grade = 'B';
        switch (grade) {
            case 'A':
                cout << "Excellent!" << endl;
                break;
            case 'B':
                cout << "Good job!" << endl;
                break;
            case 'C':
                cout << "Satisfactory." << endl;
                break;
            case 'D':
                cout << "Needs improvement." << endl;
                break;
            case 'F':
                cout << "Failed." << endl;
                break;
            default:
                cout << "Invalid grade." << endl;
                break;
        }  
    

Boolean Variables

  • Can simplify conditions.

  • Can store the result of complex conditions for later use.

  • Example

    bool isEligible = (age >= 18 && income > 30000);
    if (isEligible) {
         cout << "You qualify for the loan." << end 
    }
    

Conditional Operator (Ternary Operator)

  • Compact way to write simple if-else statements.

    condition ? expressionIfTrue : expressionIfFalse
    int age = 20;
    string status = (age >= 18) ? "adult" : "minor";
    

Common Branching Errors

  • Missing Curly Braces

  • Using Assignment Instead of Comparison

  • Floating-Point Comparison due to precision issues

Loops

Introduction to Loops

  • Loops allow a program to execute a block of code repeatedly.

  • Types of loops:

    • while loops: Execute while a condition is true

    • do-while loops: Execute at least once, then while a condition is true

    • for loops: Execute a specific number of times with controlled initialization and update

  • Loop body: The code executed repeatedly

  • Iteration: Each execution of the loop body

  • Infinite loop: A loop that never terminates

While Loops

  • Repeats a block of code as long as a specified condition is true.

    while (condition) {
        // Loop body
    }
    
    int count = 1;
    while (count <= 5) {
        cout << count << "  ";
        count++;
    }
    //Output : 1 2 3 4 5
    

Do-While Loops

  • Similar to the while loop, but the condition is checked after the loop body executes.

  • This guarantees the loop body runs at least once.

    do {
        // Loop body
    } while (condition);
    
    int number;
    do {
        cout << "Enter a positive number:  ";
        cin >> number;
    } while (number <= 0);
    

For Loops

  • Ideal when you know how many times the loop should execute.

  • Combines initialization, condition checking, and update in one line.

    for (initialization; condition; update) {
        // Loop body
    }
    
    for (int i = 0; i < 5; i++) {
        cout << i << "  ";
    }
    // Output: 0 1 2 3 4
    

Nested Loops

  • Loops can be nested inside other loops, allowing complex iterations.

    for (int i = 1; i <= 3; i++) {
        for (int j = 1; j <= 3; j++) {
            cout << "(" << i << "," << j << ")  ";
        }
        cout << endl;
    }
    //Output
    //(1,1) (1,2) (1,3)
    //(2,1) (2,2) (2,3)
    //(3,1) (3,2) (3,3)
    

Loop Control Statements

  • The break Statement

         for (int i = 1; i <= 10; i++) {
            if (i == 5) {
                 break; // Exit the loop when i is 5
                  }
                    cout << i << "  ";
                     }// Output: 1 2 3 4
    
  • The continue Statement

            for (int i = 1; i <= 10; i++) {
                 if (i % 2 == 0) {
                      continue;  // Skip even numbers
                         }
                         cout << i << "  ";
                } // Output: 1 3 5 7 9
    

Using Loops with Strings

  • Loops can process strings character by character:

    string text = "Hello";
    for (int i = 0; i < text.length(); i++) {
        cout << "Character at position " << i << ": " << text[i] << endl;
    }
    

Infinite Loops and How to Avoid Them

  • An infinite loop occurs when the loop condition never becomes false.

Choosing the Right Loop

  • for loop: Use when the number of iterations is known in advance

  • while loop: Use when the number of iterations depends on a condition

  • do-while loop: Use when you need the loop to execute at least once

Arrays and Vectors

Introduction to Arrays and Vectors

  • Arrays and vectors are collections that store multiple values of the same type.

  • They allow you to manage related data as a single unit.

    • Arrays: Fixed size, cannot be resized after declaration

    • Vectors: Dynamic size, can grow or shrink as needed

Arrays

  • Declaring and Initializing Arrays

    int numbers[5];
    
  • Accessing Array Elements using index

Vectors

  • Vectors are dynamic arrays provided by the C++ Standard Template Library (STL).

    #include <vector>
    using namespace std;
    vector<int> numbers; // Empty vector
    
  • Accessing Vector Elements using index

  • .push_back to add elements to the vector

  • .pop_back to remove the last element of the vector

  • .size to check the size of the element

  • .resize to change the vector size

  • .clear to clear all the elements of the vector

Multidimensional Arrays and Vectors

  • Two-dimensional arrays can represent tables, grids, or matrices:

    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    

Working with C-Style Strings

  • Before the string class, C++ used character arrays (C-strings) to represent strings:

  • C-strings end with a null character '\0'

  • Common C-String Functions require header

    • strcat: String concatenation

    • strcpy: String copy

    • strcmp: String comparison

    • strlen: String length

Vector/Array Operations with Loops

  • Searching for an Element

  • Transforming Values

  • Filtering Elements

  • Reversing an Array or Vector

User-Defined Functions

Introduction to Functions

  • Function Components

    • Return type - the data type of the value returned by the function

    • Name - identifier used to call the function

    • Parameters - inputs to the function optional

    • Body - the code to be executed

    returnType functionName(parameterType1 parameterName1, parameterType2 parameterName2, ...) {
        // Function body
         // Statements to be executed  return returnValue;
     }
    
  • Function Definition and Function Call

    int add(int a, int b) {
          int sum = a + b;
           return sum; }
    

Void Functions

  • Void functions don't return a value:

    void printMessage(string message) {
           cout << message << endl;
     } // Call the function printMessage("Hello, World!");
    

Functions with Return Values

  • The return statement immediately exits the function

Function Parameters

  • Parameter vs. Argument

    • Parameter: The variable listed in the function definition

    • Argument: The actual value passed to the function when called

    void greet(string name, int age) {
                  cout << "Hello, " << name << "! You are " << age << " years old." << endl; }
    
    greet("Alice", 25);
    

Default Parameter Values

  • Default parameters must be at the end of the parameter list

    void greet(string name, string greeting = "Hello") {
       cout << greeting << ", " << name << "!" << endl;
        }
    

Pass by Value vs. Pass by Reference

  • By default, function parameters are passed by value, meaning the function works with a copy of the argument:

  • To allow a function to modify the original argument, use pass by reference:

Const References

  • When passing large objects but not modifying them, use const references to avoid copying:

Function Overloading

  • Function overloading allows multiple functions with the same name but different parameter lists:

Function Declaration and Definition

  • Allows functions to be defined in any order

  • Enables forward references (using a function before its definition)

  • Helps organize code (declarations in header files, definitions in source files)

Scope and Lifetime of Variables

  • Variables defined within a function are local to that function

  • Variables defined outside any function are global

Recursion

  • Recursion is when a function calls itself

  • int factorial(int n) {

    if (n <= 1) { return 1; }
    
    return n * factorial(n - 1);
             }
    
  • Recursive functions need: A base case to stop recursion and A recursive case that makes progress toward the base case

Function Templates

  • Function templates allow you to write a function that can work with multiple data types

  • Templates allow you to write generic, type-independent code that is generated by the compiler for each specific type

    template <typename T> T maximum(T a, T b) {
    return (a > b) ? a : b;}
    

Unit Testing Functions

  • Unit testing verifies that functions work correctly:

  • Test normal cases, Test edge cases (like zero, negative numbers, etc.) and Test boundary cases
    *Verify expected behavior with different inputs

Objects and Classes

Introduction to Object-Oriented Programming

  • Object-Oriented Programming (OOP) is a programming paradigm that organizes code around objects, which are instances of classes.

  • A class definition includes data members (attributes) and member functions (methods):

  • Key Concepts in OOP

    • Objects: Entities that combine data (attributes) and behavior (methods)

    • Classes: Templates or blueprints for creating objects

    • Encapsulation: Bundling data and methods together, controlling access

    • Abstraction: Hiding complex implementation details while exposing necessary functionality

    • Inheritance: Creating new classes based on existing classes

    • Polymorphism: Allowing objects of different types to be treated as objects of a common type

Creating and Using Classes

  • Class structure is shown below:

    class Dog {
        private:
           string name;
            int age;
                double weight;
                public:
                void setName(string dogName) {
                 name = dogName;
                    }
                   string getName() {
                        return name;
                    }
                    void setAge(int dogAge) {
                     age = dogAge;
                      }
                    int getAge() {
                         return age;
                     }
                    void bark() {
                    cout << name << " says: Woof!" << endl;
                        }
        };
    

Access Specifiers

  • public: Members are accessible from outside the class

  • private: Members are only accessible within the class

  • protected: Members are accessible within the class and its derived classes

Constructors and Destructors

  • Constructors are special member functions that are called when an object is created:

  • Constructors Constructor Overloading, more that one constructor with different parameters

Member Functions

  • Member functions define the behavior of objects:

  • Functions defined inside the class declaration are automatically inline:

  • Functions can be defined outside the class using the scope resolution operator (::):

Const Member Functions

  • Functions that do not modify class data should be marked as const:

Access Functions: Getters and Setters

*. Getters and setters provide controlled access to private data members:

```cpp
class Student {
private:
string name;
int id;
double gpa;
public:

Student() : name(""), id(0), gpa(0.0) {}
Student(string n, int i, double g) : name(n), id(i), gpa(g) {}

string getName() const {return name; }
int getID() const { return id; }
double getGPA() const { return gpa; }

void setName(string n) { name = n; }

void setID(int i) { id = i; }

void setGPA(double g) {
if (g >= 0.0 && g <= 4.0) { gpa = g; } else { cout << "Invalid GPA value"(