HSSLIVE Plus One Computer Science Chapter 10: Functions Notes

Functions enable modular programming by breaking large problems into manageable, reusable components. This chapter explains how to define, declare, and call functions in C++, covering parameter passing mechanisms (by value, by reference), return values, and function overloading. It emphasizes the importance of scope, lifetime of variables, and the role of functions in creating abstraction layers that hide implementation details. The chapter also introduces recursive functions and demonstrates how complex problems can be solved through recursive thinking.

Chapter 10: Functions

Functions are blocks of code designed to perform specific tasks. They help in organizing code, promoting reusability, and making programs more manageable. This chapter explores the concept of functions in C++ and their various applications.

Introduction to Functions

A function is a self-contained block of code that performs a specific task. Functions help in:

  • Breaking down complex problems into smaller, manageable parts
  • Avoiding code duplication
  • Improving code readability and organization
  • Facilitating code reuse
  • Supporting modular programming

Function Definition and Declaration

Function Declaration (Prototype)

A function declaration tells the compiler about a function’s name, return type, and parameters. It’s also called a function prototype.

Syntax:

cpp

return_type function_name(parameter_list);

Example:

cpp

int add(int a, int b);  // Function prototype

Function Definition

A function definition includes the function’s implementation.

Syntax:

cpp

return_type function_name(parameter_list) {
    // Function body
    // Statements
    return value;  // for non-void functions
}

Example:

cpp

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

Function Call

A function call invokes the function to execute its code.

Example:

cpp

int result = add(5, 3);  // Function call

Components of a Function

  1. Return Type: Specifies the type of value the function returns
    • void for functions that don’t return a value
    • Data type (int, float, char, etc.) for functions that return a value
  2. Function Name: Identifier for the function
    • Should be meaningful and descriptive
    • Follows naming conventions
  3. Parameters: Input values passed to the function
    • Formal parameters: In function declaration/definition
    • Actual parameters (arguments): In function call
  4. Function Body: Contains the statements to be executed

Types of Functions

Built-in Functions (Library Functions)

These are pre-defined functions provided by C++ libraries.

Examples:

  • Mathematical functions: sqrt(), pow(), abs()
  • Character functions: isalpha(), isdigit(), toupper()
  • String functions: strlen(), strcpy(), strcat()
  • Input/Output functions: cin.getline(), cout.width()
cpp

#include <cmath>
#include <iostream>
using namespace std;

int main() {
    double x = 16.0;
    double squareRoot = sqrt(x);  // Built-in function
    cout << "Square root of " << x << " is " << squareRoot << endl;
    return 0;
}

User-defined Functions

These are functions created by the programmer.

Example:

cpp

#include <iostream>
using namespace std;

// User-defined function to calculate the area of a rectangle
double calculateArea(double length, double width) {
    return length * width;
}

int main() {
    double l = 5.0, w = 3.0;
    double area = calculateArea(l, w);  // User-defined function call
    cout << "Area of rectangle: " << area << endl;
    return 0;
}

Parameter Passing Mechanisms

Pass by Value

In pass by value, a copy of the argument is passed to the function. Changes to the parameter inside the function don’t affect the original argument.

cpp

void increment(int x) {
    x++;  // Only the local copy is affected
    cout << "Inside function: x = " << x << endl;
}

int main() {
    int num = 5;
    cout << "Before function call: num = " << num << endl;  // 5
    increment(num);  // Pass by value
    cout << "After function call: num = " << num << endl;   // Still 5
    return 0;
}

Pass by Reference

In pass by reference, a reference to the argument is passed to the function. Changes to the parameter inside the function affect the original argument.

cpp

void increment(int &x) {
    x++;  // Original value is modified
    cout << "Inside function: x = " << x << endl;
}

int main() {
    int num = 5;
    cout << "Before function call: num = " << num << endl;  // 5
    increment(num);  // Pass by reference
    cout << "After function call: num = " << num << endl;   // 6
    return 0;
}

Pass by Address (Pointer)

In pass by address, the memory address of the argument is passed to the function. Changes to the dereferenced pointer inside the function affect the original argument.

cpp

void increment(int *x) {
    (*x)++;  // Original value is modified
    cout << "Inside function: *x = " << *x << endl;
}

int main() {
    int num = 5;
    cout << "Before function call: num = " << num << endl;  // 5
    increment(&num);  // Pass by address
    cout << "After function call: num = " << num << endl;   // 6
    return 0;
}

Function Overloading

Function overloading allows multiple functions to have the same name but different parameter lists.

cpp

#include <iostream>
using namespace std;

// Function overloading

// Version 1: Takes two integers
int add(int a, int b) {
    return a + b;
}

// Version 2: Takes three integers
int add(int a, int b, int c) {
    return a + b + c;
}

// Version 3: Takes two doubles
double add(double a, double b) {
    return a + b;
}

int main() {
    cout << add(5, 3) << endl;         // Calls version 1
    cout << add(5, 3, 2) << endl;      // Calls version 2
    cout << add(5.2, 3.7) << endl;     // Calls version 3
    return 0;
}

Functions are overloaded based on:

  • Number of parameters
  • Types of parameters
  • Order of parameters

Return type alone is not sufficient to overload a function.

Default Arguments

Default arguments specify default values for parameters if no argument is provided in the function call.

cpp

#include <iostream>
using namespace std;

// Function with default arguments
void displayInfo(string name, int age = 18, string course = "Computer Science") {
    cout << "Name: " << name << endl;
    cout << "Age: " << age << endl;
    cout << "Course: " << course << endl;
}

int main() {
    // All arguments provided
    displayInfo("Priya", 20, "Physics");
    
    cout << endl;
    
    // Only name provided, others use default values
    displayInfo("Raj");
    
    cout << endl;
    
    // Name and age provided, course uses default value
    displayInfo("Aman", 22);
    
    return 0;
}

Rules for default arguments:

  • Default arguments must be the rightmost parameters
  • Once a default value is specified, all parameters to its right must also have default values

Inline Functions

Inline functions are expanded at the point of call, potentially improving performance by avoiding function call overhead.

cpp

#include <iostream>
using namespace std;

// Inline function
inline int square(int x) {
    return x * x;
}

int main() {
    int num = 5;
    cout << "Square of " << num << " is " << square(num) << endl;
    return 0;
}

Inline functions are suitable for:

  • Small, simple functions
  • Functions called frequently
  • Performance-critical code sections

However, excessive use of inline functions can increase the binary size.

Recursive Functions

A recursive function is one that calls itself directly or indirectly.

cpp

#include <iostream>
using namespace std;

// Recursive function to calculate factorial
int factorial(int n) {
    // Base case
    if (n == 0 || n == 1) {
        return 1;
    }
    // Recursive case
    else {
        return n * factorial(n-1);
    }
}

int main() {
    int num = 5;
    cout << "Factorial of " << num << " is " << factorial(num) << endl;
    return 0;
}

Components of a recursive function:

  • Base case: Condition where recursion stops
  • Recursive case: Function calls itself with a simpler version of the problem

Examples of problems solved using recursion:

  • Factorial calculation
  • Fibonacci series
  • Tower of Hanoi
  • Binary search
  • Tree traversal

Function Templates

Function templates allow creating generic functions that work with different data types.

cpp

#include <iostream>
using namespace std;

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

int main() {
    cout << "Max of 5 and 10: " << maximum(5, 10) << endl;
    cout << "Max of 5.5 and 3.7: " << maximum(5.5, 3.7) << endl;
    cout << "Max of 'A' and 'Z': " << maximum('A', 'Z') << endl;
    return 0;
}

Benefits of function templates:

  • Code reusability
  • Type safety
  • Flexibility

Scope of Variables

The scope of a variable determines where it can be accessed.

Local Variables

Local variables are declared inside a block (function, loop, etc.) and are accessible only within that block.

cpp

void function() {
    int localVar = 10;  // Local variable
    cout << localVar << endl;  // Accessible here
}

int main() {
    // cout << localVar << endl;  // Error: localVar not accessible here
    return 0;
}

Global Variables

Global variables are declared outside all functions and are accessible throughout the program.

cpp

#include <iostream>
using namespace std;

int globalVar = 20;  // Global variable

void function() {
    cout << "Inside function: " << globalVar << endl;  // Accessible here
}

int main() {
    cout << "Inside main: " << globalVar << endl;  // Accessible here
    function();
    return 0;
}

Static Variables

Static local variables retain their value between function calls.

cpp

#include <iostream>
using namespace std;

void countCalls() {
    static int count = 0;  // Static local variable
    count++;
    cout << "Function called " << count << " times." << endl;
}

int main() {
    countCalls();  // Output: Function called 1 times.
    countCalls();  // Output: Function called 2 times.
    countCalls();  // Output: Function called 3 times.
    return 0;
}

Practical Applications of Functions

Example 1: Calculator Program

cpp

#include <iostream>
using namespace std;

// Function prototypes
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);

int main() {
    char operation;
    double num1, num2, result;
    
    cout << "Enter first number: ";
    cin >> num1;
    cout << "Enter operation (+, -, *, /): ";
    cin >> operation;
    cout << "Enter second number: ";
    cin >> num2;
    
    switch (operation) {
        case '+':
            result = add(num1, num2);
            break;
        case '-':
            result = subtract(num1, num2);
            break;
        case '*':
            result = multiply(num1, num2);
            break;
        case '/':
            if (num2 != 0) {
                result = divide(num1, num2);
            } else {
                cout << "Error: Division by zero!" << endl;
                return 1;
            }
            break;
        default:
            cout << "Invalid operation!" << endl;
            return 1;
    }
    
    cout << num1 << " " << operation << " " << num2 << " = " << result << endl;
    return 0;
}

// Function definitions
double add(double a, double b) {
    return a + b;
}

double subtract(double a, double b) {
    return a - b;
}

double multiply(double a, double b) {
    return a * b;
}

double divide(double a, double b) {
    return a / b;
}

Example 2: Prime Number Checker using Function

cpp

#include <iostream>
#include <cmath>
using namespace std;

// Function to check if a number is prime
bool isPrime(int num) {
    // Handle special cases
    if (num <= 1) {
        return false;
    }
    if (num <= 3) {
        return true;
    }
    if (num % 2 == 0 || num % 3 == 0) {
        return false;
    }
    
    // Check for divisibility by numbers of the form 6k ± 1
    for (int i = 5; i * i <= num; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) {
            return false;
        }
    }
    
    return true;
}

int main() {
    int number;
    
    cout << "Enter a positive integer: ";
    cin >> number;
    
    if (isPrime(number)) {
        cout << number << " is a prime number." << endl;
    } else {
        cout << number << " is not a prime number." << endl;
    }
    
    return 0;
}

Example 3: Student Marks Analysis Using Functions

cpp

#include <iostream>
using namespace std;

// Function prototypes
void inputMarks(int marks[], int size);
double calculateAverage(int marks[], int size);
int findHighest(int marks[], int size);
int findLowest(int marks[], int size);
void displayStats(int marks[], int size);

int main() {
    const int NUM_SUBJECTS = 5;
    int marks[NUM_SUBJECTS];
    
    cout << "Enter marks for " << NUM_SUBJECTS << " subjects:" << endl;
    inputMarks(marks, NUM_SUBJECTS);
    
    displayStats(marks, NUM_SUBJECTS);
    
    return 0;
}

// Function to input marks
void inputMarks(int marks[], int size) {
    for (int i = 0; i < size; i++) {
        cout << "Subject " << i+1 << ": ";
        cin >> marks[i];
        
        // Validate marks
        while (marks[i] < 0 || marks[i] > 100) {
            cout << "Invalid marks! Enter again (0-100): ";
            cin >> marks[i];
        }
    }
}

// Function to calculate average marks
double calculateAverage(int marks[], int size) {
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += marks[i];
    }
    return static_cast<double>(sum) / size;
}

// Function to find highest marks
int findHighest(int marks[], int size) {
    int highest = marks[0];
    for (int i = 1; i < size; i++) {
        if (marks[i] > highest) {
            highest = marks[i];
        }
    }
    return highest;
}

// Function to find lowest marks
int findLowest(int marks[], int size) {
    int lowest = marks[0];
    for (int i = 1; i < size; i++) {
        if (marks[i] < lowest) {
            lowest = marks[i];
        }
    }
    return lowest;
}

// Function to display statistics
void displayStats(int marks[], int size) {
    cout << "\nMarks Analysis:" << endl;
    cout << "---------------" << endl;
    
    double average = calculateAverage(marks, size);
    int highest = findHighest(marks, size);
    int lowest = findLowest(marks, size);
    
    cout << "Average marks: " << average << endl;
    cout << "Highest marks: " << highest << endl;
    cout << "Lowest marks: " << lowest << endl;
    
    cout << "\nGrade: ";
    if (average >= 90) {
        cout << "A+" << endl;
    } else if (average >= 80) {
        cout << "A" << endl;
    } else if (average >= 70) {
        cout << "B+" << endl;
    } else if (average >= 60) {
        cout << "B" << endl;
    } else if (average >= 50) {
        cout << "C" << endl;
    } else if (average >= 40) {
        cout << "D" << endl;
    } else {
        cout << "F" << endl;
    }
}

Functions are essential building blocks in C++ programming that promote modular, organized, and reusable code. They allow complex problems to be broken down into smaller, manageable parts, making programs easier to develop, test, and maintain. Understanding different aspects of functions provides programmers with powerful tools to create efficient and readable code.

Complete Chapter-wise Hsslive Plus One Computer Science Notes

Our HSSLive Plus One Computer Science Notes cover all chapters with key focus areas to help you organize your study effectively:

Leave a Comment