Contents
Functions
Functions in C++
A function is a set of statements designed to perform a specific task and is executed only when called. Functions allow you to modularize code, reducing redundancy and improving clarity. By encapsulating common tasks within functions, we avoid repeating the same logic multiple times, making the code more manageable and easier to maintain.
Syntax:
void function(int size)
{
int array[size];
// code to manipulate the array
}
Example:
// C++ Program to demonstrate the working of a function
#include
using namespace std;
// Function that takes two integers as parameters
// and returns the larger of the two
int max(int x, int y) {
return (x > y) ? x : y;
}
int main() {
int a = 15, b = 25;
// Calling the max function
int result = max(a, b);
cout << "The maximum value is " << result;
return 0;
}
Output:
The maximum value is 25
Why Do We Need Functions?
- Code Reusability: Avoid redundancy by reusing functions across the program.
- Modularity: Code becomes more organized and easier to understand when divided into functions.
- Abstraction: Using functions hides internal details, making complex tasks easier to use through simple function calls.
Function Declaration
A function declaration tells the compiler about the function’s name, parameters, and return type. Here is an example:
// Function declarations
int add(int, int); // Function with two integer parameters
float subtract(float, int); // Function with float and int parameters
char* reverseString(char*); // Function that returns a char pointer
Types of Functions
1. User-defined Functions: Functions created by the user to perform specific tasks.
2. Library Functions: Predefined functions in C++ that you can use directly, such as sqrt(), strlen(), etc
Passing Parameters to Functions
There are two common ways to pass parameters to functions:
- Pass by Value: A copy of the variable is passed. Modifications inside the function do not affect the original variable.
- Pass by Reference: The function receives the memory address of the variable, and changes made inside the function affect the original variable.
Function Example: Pass by Value
#include
using namespace std;
void modify(int x) {
x = 50; // Changes won't affect the original variable
}
int main() {
int num = 10;
modify(num);
cout << "Value of num: " << num; // Outputs 10
return 0;
}
Function Example: Pass by Reference
#include
using namespace std;
void modify(int &x) {
x = 50; // Changes will affect the original variable
}
int main() {
int num = 10;
modify(num);
cout << "Value of num: " << num; // Outputs 50
return 0;
}
Function Returning a String example:
#include
#include
std::string greet() {
return "Hello, C++!";
}
int main() {
std::string message = greet();
cout << message;
return 0;
}
Output:
Hello, C++!
Function Returning a Pointer example:
#include
using namespace std;
int* createArray(int size) {
int* arr = new int[size]; // Dynamically allocate memory
for (int i = 0; i < size; ++i) {
arr[i] = i * 2;
}
return arr;
}
int main() {
int* arr = createArray(5);
for (int i = 0; i < 5; ++i) {
cout << arr[i] << " "; // Outputs: 0 2 4 6 8
}
delete[] arr; // Free allocated memory
return 0;
}
Output:
0 2 4 6 8
Callback Function Example:
#include
using namespace std;
typedef void (*Callback)(); // Define a callback function type
void action(Callback callback) {
cout << "Performing action...\n";
callback(); // Call the passed callback function
}
void myCallback() {
cout << "Callback function executed!";
}
int main() {
action(myCallback);
return 0;
}
Output:
Performing action...
Callback function executed!
Differences Between Call by Value and Call by Reference
Call by Value | Call by Reference |
---|---|
A copy of the value is passed. | The reference (memory address) is passed. |
Changes do not affect the original. | Changes affect the original. |
Actual and formal parameters are stored at different locations. | Actual and formal parameters share the same location. |
return statement
The return
statement in C++ transfers control back to the function that invoked the current function. Once the return
statement is executed, the function ends and any subsequent code in that function is ignored. For non-void functions, a return
statement must return a value, while in void functions, the return
statement can be omitted or used without returning any value.
Syntax:
return [expression];
Functions Without a Return Value (void
Functions)
In C++, if a function is defined with a void
return type, it does not return any value. The return
statement is optional and can be used to exit the function early, but it should not return any value.
Example:
// C++ Program demonstrating a void function without a return statement
#include
using namespace std;
void displayMessage() {
cout << "Hello, World!";
}
int main() {
displayMessage(); // Function call
return 0;
}
Output:
Hello, World!
Functions With return
in a Void Function:
In a void function, the return
statement can be used simply to exit the function early.
Example:
// C++ Program using return in a void function
#include
using namespace std;
void checkValue(int x) {
if (x < 0) {
return; // Exit the function early if x is negative
}
cout << "The value is non-negative: " << x << endl;
}
int main() {
checkValue(-5); // Function call
checkValue(10); // Function call
return 0;
}
Output
The value is non-negative: 10
Default Arguments in C++
In C++, a default argument is a value that is automatically provided by the compiler when a calling function does not specify a value for the argument. If a value is passed for the argument, it overrides the default value.
Example : Default Arguments in a Function
The following C++ example demonstrates the use of default arguments. We don’t need to write multiple functions for different numbers of arguments; one function can handle various cases by using default values for some parameters.
// C++ Program to demonstrate Default Arguments
#include
using namespace std;
// Function with default arguments
// It can be called with 2, 3, or 4 arguments.
int sum(int x, int y, int z = 0, int w = 0) {
return (x + y + z + w);
}
// Driver Code
int main() {
// Case 1: Passing two arguments
cout << sum(10, 15) << endl;
// Case 2: Passing three arguments
cout << sum(10, 15, 25) << endl;
// Case 3: Passing four arguments
cout << sum(10, 15, 25, 30) << endl;
return 0;
}
Output:
25
50
80
Key Points to Remember:
1. Inlining is a suggestion, not a directive. The compiler may choose to ignore the inline request.
2. The compiler may not inline the function if it contains:
- Loops (for, while, or do-while)
- Static variables
- Recursive calls
- A return type other than void and lacks a return statement
- Complex constructs such as switch or goto
Why Use Inline Functions?
When a function is called, there’s an overhead for:
1. Storing the return address
2. Passing function arguments
3. Transferring control to the function’s code
4. Returning the result from the function
For small and frequently called functions, this overhead might exceed the time it takes to execute the function itself. By inlining such functions, you avoid the cost of the function call and may improve performance. Inline functions are beneficial for small, simple functions where function call overhead might be significant relative to execution time.
Advantages of Inline Functions:
Reduced Function Call Overhead: No need to jump to a new memory address for function execution.
No Stack Push/Pop Overhead: Parameters don’t need to be pushed or popped from the stack.
No Return Overhead: Control doesn’t need to be returned to the caller.
Potential for Context-Specific Optimization: The compiler can perform optimizations that wouldn’t be possible with regular function calls, as the function’s code is available at the point of use.
Smaller Code Size for Embedded Systems: Inlining small functions can sometimes produce more compact code in certain situations (e.g., embedded systems).
Example:
// Inline function to calculate the square of a number
#include
using namespace std;
inline int square(int x) {
return x * x;
}
int main() {
int num = 5;
// Using the inline function
cout << "Square of " << num << " is " << square(num) << endl;
// Another usage of the inline function
cout << "Square of 10 is " << square(10) << endl;
return 0;
}
Output:
Square of 5 is 25
Square of 10 is 100
Lambda Expressions
C++11 introduced lambda expressions, which allow you to write inline functions for short snippets of code without giving them a name. These functions are useful for situations where you won’t reuse the code, and therefore don’t need to define a separate function.
Syntax:
// C++ program demonstrating lambda expressions
#include
#include
#include
#include // for accumulate
using namespace std;
// Function to print vector
void printVector(vector v)
{
// Lambda expression to print vector elements
for_each(v.begin(), v.end(), [](int i)
{
cout << i << " ";
});
cout << endl;
}
int main()
{
vector v {4, 1, 3, 5, 2, 3, 1, 7};
printVector(v);
// Finding the first number greater than 4
auto p = find_if(v.begin(), v.end(), [](int i)
{
return i > 4;
});
cout << "First number greater than 4 is : " << *p << endl;
// Sorting the vector in descending order
sort(v.begin(), v.end(), [](int a, int b) -> bool
{
return a > b;
});
printVector(v);
// Counting numbers greater than or equal to 5
int count_5 = count_if(v.begin(), v.end(), [](int a)
{
return a >= 5;
});
cout << "The number of elements greater than or equal to 5 is : "
<< count_5 << endl;
// Removing duplicate elements
auto unique_end = unique(v.begin(), v.end(), [](int a, int b)
{
return a == b;
});
v.resize(distance(v.begin(), unique_end));
printVector(v);
// Calculating factorial using accumulate
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int factorial = accumulate(arr, arr + 10, 1, [](int i, int j)
{
return i * j;
});
cout << "Factorial of 10 is : " << factorial << endl;
// Storing a lambda in a variable to compute square
auto square = [](int i)
{
return i * i;
};
cout << "Square of 5 is : " << square(5) << endl;
return 0;
}
Output:
4 1 3 5 2 3 1 7
First number greater than 4 is : 5
7 5 4 3 3 2 1 1
The number of elements greater than or equal to 5 is : 2
7 5 4 3 2 1
Factorial of 10 is : 3628800
Square of 5 is : 25