Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
42 views9 pages

Chapter 2

Uploaded by

tommyassefa95
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views9 pages

Chapter 2

Uploaded by

tommyassefa95
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Chapter 2: Functions in C++

Functions are fundamental building blocks in C++ programming that help organize code,
promote reusability, and improve readability. This chapter delves into the basic concepts,
declarations, definitions, components, invocation methods, and recursion in functions.
2.1. Basic Concept and Need of Functions
Concept of Functions:
A function is a self-contained block of code designed to perform a specific task. Functions can
be called multiple times throughout a program, allowing for code reuse and modularity.
Need for Functions:
 Modularity: Breaks down complex problems into smaller, manageable tasks.
 Reusability: Allows the same code to be used multiple times without duplication.
 Maintainability: Simplifies debugging and updating code by isolating functionality.
 Readability: Enhances code clarity by abstracting complex operations into descriptive function
names.
Example:
#include <iostream>
// Function declaration
void greet();

int main() {
greet(); // Function call
greet();
return 0;
}

// Function definition
void greet() {
std::cout << "Hello, World!" << std::endl;
}
Output:
Hello, World!
Hello, World!
2.2. Declaring and Defining a Function
Function Declaration (Prototype):
A function declaration informs the compiler about the function's name, return type, and
parameters without providing the actual body. It is typically placed before the main() function
or in a header file.
Syntax:
return_type function_name(parameter_list);
Example:
int add(int a, int b); // Function declaration
Function Definition:
A function definition provides the actual body of the function, including the code that performs
the task.
Syntax:
return_type function_name(parameter_list) {
// Function body
}
Example:
int add(int a, int b) { // Function definition
return a + b;
}
Complete Example:
#include <iostream>
// Function declaration
int add(int a, int b);

int main() {
int sum = add(5, 3); // Function call
std::cout << "Sum: " << sum;
return 0;
}

// Function definition
int add(int a, int b) {
return a + b;
}
Output:
Sum: 8
2.3. Function Components (Parameters and Arguments)
Parameters vs. Arguments:
 Parameters: Variables listed in the function's declaration and definition. They act as
placeholders for the values that will be passed to the function.
 Arguments: Actual values passed to the function when it is called.
Example:
#include <iostream>
// Function with parameters
void displayMessage(std::string message, int times);

int main() {
// Function call with arguments
displayMessage("Hello!", 3);
return 0;
}

// Function definition
void displayMessage(std::string message, int times) {
for (int i = 0; i < times; ++i) {
std::cout << message << std::endl;
}
}
Output:
Hello!
Hello!
Hello!
Default Parameters:
C++ allows functions to have default parameter values, which are used if no corresponding
argument is provided during the function call.
Example:
#include <iostream>
// Function with default parameter
void greet(std::string name = "Guest") {
std::cout << "Hello, " << name << "!" << std::endl;
}

int main() {
greet("Alice"); // Output: Hello, Alice!
greet(); // Output: Hello, Guest!
return 0;
}
2.4. Calling/Invoking Functions by Value and Reference Parameters
Functions can receive arguments either by value or by reference, affecting how data is passed
and manipulated within the function.
Passing by Value:
When arguments are passed by value, a copy of the data is made. Changes to parameters within
the function do not affect the original arguments.
Syntax:
return_type function_name(parameter_type parameter_name);
Example:
#include <iostream>
// Function that modifies a copy of the argument
void incrementByValue(int num) {
num += 1;
std::cout << "Inside function (by value): " << num << std::endl;
}

int main() {
int number = 5;
incrementByValue(number); // Output: 6
std::cout << "Outside function: " << number << std::endl; // Output: 5
return 0;
}
Output:
Inside function (by value): 6
Outside function: 5
Passing by Reference:
When arguments are passed by reference, the function receives a reference to the original data.
Changes to parameters within the function affect the original arguments.
Syntax:
return_type function_name(parameter_type &parameter_name);
Example:
#include <iostream>
// Function that modifies the original argument
void incrementByReference(int &num) {
num += 1;
std::cout << "Inside function (by reference): " << num << std::endl;
}

int main() {
int number = 5;
incrementByReference(number); // Output: 6
std::cout << "Outside function: " << number << std::endl; // Output: 6
return 0;
}
Output:
Inside function (by reference): 6
Outside function: 6
Passing by Pointer:
Another way to pass arguments by reference is using pointers. This method involves passing the
memory address of the variable.
Example:
#include <iostream>
// Function that modifies the original argument using pointer
void incrementByPointer(int *num) {
(*num) += 1;
std::cout << "Inside function (by pointer): " << *num << std::endl;
}

int main() {
int number = 5;
incrementByPointer(&number); // Output: 6
std::cout << "Outside function: " << number << std::endl; // Output: 6
return 0;
}
Output:
Inside function (by pointer): 6
Outside function: 6
Choosing Between Pass by Value and Pass by Reference:
 Use Pass by Value when the function does not need to modify the original data and when
working with small data types to avoid unnecessary overhead.
 Use Pass by Reference when the function needs to modify the original data or when working
with large data types to improve performance by avoiding copies.
2.5. Functions and Recursion
Recursion:
Recursion is a programming technique where a function calls itself to solve smaller instances of
the same problem. It is particularly useful for problems that can be broken down into similar
subproblems, such as factorial calculation, Fibonacci series, and tree traversals.
Key Components of Recursion:
1. Base Case: The condition under which the recursion stops. It prevents infinite loops.
2. Recursive Case: The part of the function where the function calls itself with modified
parameters to approach the base case.
Example 1: Factorial Calculation
Factorial Definition:
 n! = n * (n-1)!
 Base Case: 0! = 1
Recursive Function:
#include <iostream>
// Recursive function to calculate factorial
long long factorial(int n) {
if (n < 0) {
std::cout << "Factorial not defined for negative numbers." <<
std::endl;
return -1;
}
if (n == 0) { // Base case
return 1;
} else { // Recursive case
return n * factorial(n - 1);
}
}

int main() {
int number = 5;
long long result = factorial(number);
if (result != -1) {
std::cout << "Factorial of " << number << " is " << result;
}
return 0;
}
Output:
Factorial of 5 is 120
Example 2: Fibonacci Series
Fibonacci Definition:
 F(n) = F(n-1) + F(n-2)
 Base Cases: F(0) = 0, F(1) = 1
Recursive Function:
#include <iostream>
// Recursive function to calculate Fibonacci number
int fibonacci(int n) {
if (n < 0) {
std::cout << "Fibonacci not defined for negative numbers." <<
std::endl;
return -1;
}
if (n == 0) { // Base case
return 0;
} else if (n == 1) { // Base case
return 1;
} else { // Recursive case
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
int main() {
int position = 7;
int fib = fibonacci(position);
if (fib != -1) {
std::cout << "Fibonacci number at position " << position << " is " <<
fib;
}
return 0;
}
Output:
arduino
Copy code
Fibonacci number at position 7 is 13
Considerations for Using Recursion:
 Efficiency: Recursive solutions can be less efficient due to repeated calculations and increased
memory usage (stack frames). Techniques like memoization can optimize recursive functions.
 Stack Overflow: Deep recursion can lead to stack overflow errors. Ensure that the base case is
reachable and that recursion depth is manageable.
 Alternatives: Iterative solutions using loops are often more efficient and preferable for problems
where recursion does not provide significant benefits.
Example 3: Recursive vs. Iterative Factorial
Recursive Approach:
#include <iostream>
// Recursive factorial
long long recursiveFactorial(int n) {
if (n == 0) return 1;
return n * recursiveFactorial(n - 1);
}
Iterative Approach:
cpp
Copy code
#include <iostream>

// Iterative factorial
long long iterativeFactorial(int n) {
if (n < 0) return -1;
long long result = 1;
for(int i = 1; i <= n; ++i){
result *= i;
}
return result;
}
Usage in main():
cpp
Copy code
int main() {
int number = 5;
std::cout << "Recursive Factorial of " << number << " is " <<
recursiveFactorial(number) << std::endl;
std::cout << "Iterative Factorial of " << number << " is " <<
iterativeFactorial(number) << std::endl;
return 0;
}
Output:
csharp
Copy code
Recursive Factorial of 5 is 120
Iterative Factorial of 5 is 120
Choosing Between Recursive and Iterative Approaches:
 Use Recursion when the problem naturally fits a recursive pattern (e.g., tree traversals, divide-
and-conquer algorithms).
 Use Iteration for better performance and when dealing with large datasets or when recursion
depth could be an issue.

You might also like