In C++, functions are reusable blocks of code that perform specific tasks and can be called from other parts of a program.
Functions help make code modular, readable, and maintainable by breaking down complex tasks into smaller, manageable pieces.
C++ provides various types of functions, including simple functions, functions with parameters, overloaded functions, and recursive functions.
Basic Syntax of a Function
return_type function_name(parameter_list) { // Function body return value; // Optional, depends on return type }
1. Basic Function Example
A simple function that performs addition.
#include <iostream> using namespace std; int add(int a, int b) { return a + b; } int main() { int result = add(5, 3); cout << "5 + 3 = " << result << endl; return 0; }
Explanation:
- add is a function that takes two integers, adds them, and returns the result.
- add(5, 3) is called in main, and the result is displayed.
Output:
5 + 3 = 8
2. Function with Default Parameters
You can specify default values for function parameters, making them optional.
#include <iostream> using namespace std; int multiply(int a, int b = 2) { return a * b; } int main() { cout << "5 * 2 = " << multiply(5) << endl; // Uses default b = 2 cout << "5 * 3 = " << multiply(5, 3) << endl; // b is overridden by 3 return 0; }
Explanation:
- multiply has a default value of 2 for b.
- When called as multiply(5), b is 2 by default; when called as multiply(5, 3), b is overridden to 3.
Output:
5 * 2 = 10 5 * 3 = 15
3. Function Overloading
Function overloading allows multiple functions with the same name but different parameter lists.
#include <iostream> using namespace std; int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } int main() { cout << "Integer addition: " << add(5, 3) << endl; // Calls int version cout << "Double addition: " << add(2.5, 3.1) << endl; // Calls double version return 0; }
Explanation:
- There are two add functions, one for int and another for double.
- The compiler selects the correct function based on the argument types.
Output:
Integer addition: 8 Double addition: 5.6
4. Inline Functions
An inline function suggests to the compiler to expand the function code at each call instead of performing a function call, potentially improving performance.
#include <iostream> using namespace std; inline int square(int x) { return x * x; } int main() { cout << "Square of 4: " << square(4) << endl; return 0; }
Explanation:
- inline is used to suggest inlining, which eliminates the function call overhead for square.
Output:
Square of 4: 16
5. Passing Parameters by Value
Passing parameters by value means that changes to the parameter inside the function do not affect the original argument.
#include <iostream> using namespace std; void increment(int x) { x++; cout << "Inside function: " << x << endl; } int main() { int num = 10; increment(num); cout << "Outside function: " << num << endl; return 0; }
Explanation:
- increment modifies x inside the function, but num in main remains unaffected.
Output:
Inside function: 11 Outside function: 10
6. Passing Parameters by Reference
Passing parameters by reference allows the function to modify the original argument.
#include <iostream> using namespace std; void increment(int &x) { x++; cout << "Inside function: " << x << endl; } int main() { int num = 10; increment(num); cout << "Outside function: " << num << endl; return 0; }
Explanation:
- &x allows increment to modify num in main, affecting the original value.
Output:
Inside function: 11 Outside function: 11
7. Passing Parameters by Pointer
Passing parameters by pointer also allows a function to modify the original argument by using pointers.
#include <iostream> using namespace std; void increment(int *x) { (*x)++; cout << "Inside function: " << *x << endl; } int main() { int num = 10; increment(&num); cout << "Outside function: " << num << endl; return 0; }
Explanation:
- increment uses a pointer to modify the original value of num.
Output:
Inside function: 11 Outside function: 11
8. Recursive Functions
A recursive function is a function that calls itself, commonly used in tasks like calculating factorials or Fibonacci numbers.
#include <iostream> using namespace std; int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } int main() { int num = 5; cout << "Factorial of " << num << " is " << factorial(num) << endl; return 0; }
Explanation:
- factorial calls itself with a smaller value of n until it reaches the base case (n <= 1).
Output:
Factorial of 5 is 120
9. Function with Return by Reference
A function can return a reference, allowing the caller to modify the returned variable directly.
#include <iostream> using namespace std; int& getStaticVar() { static int x = 10; return x; } int main() { int &ref = getStaticVar(); cout << "Original value: " << ref << endl; ref = 20; cout << "Modified value: " << getStaticVar() << endl; return 0; }
Explanation:
- getStaticVar returns a reference to a static variable, which persists between calls.
Output:
Original value: 10 Modified value: 20
10. Lambda Functions
A lambda function is an anonymous function that can be defined inline. Lambda expressions are especially useful for short, simple functions.
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; int sum = 0; for_each(numbers.begin(), numbers.end(), [&sum](int x) { sum += x; }); cout << "Sum of elements: " << sum << endl; return 0; }
Explanation:
- [&sum](int x) { sum += x; } is a lambda function that takes each element and adds it to sum.
- for_each applies this lambda to each element in numbers.
Output:
Sum of elements: 15
11. Function Templates
Function templates allow you to create generic functions that work with different data types.
#include <iostream> using namespace std; template <typename T> T add(T a, T b) { return a + b; } int main() { cout << "Integer addition: " << add(5, 3) << endl; cout << "Double addition: " << add(2.5, 3.1) << endl; return 0; }
Explanation:
- add is a template function that can handle different types (int, double) based on the argument types provided.
Output:
Integer addition: 8 Double addition: 5.6
Summary Table of Function Types
Example Type | Description |
---|---|
Basic Function | A simple function that adds two integers |
Function with Default Parameters | Function with default values for parameters |
Function Overloading | Multiple functions with the same name but different parameter lists |
Inline Function | Suggested for inlining to avoid function call overhead |
Passing by Value | Parameters passed by value, original value unchanged |
Passing by Reference | Parameters passed by reference, original value modified |
Passing by Pointer | Parameters passed by pointer, original value modified |
Recursive Function | Function that calls itself, useful for recursive algorithms |
Return by Reference | Returns a reference to allow modification of the returned variable |
Lambda Function | Inline anonymous function, useful for short and simple operations |
Function Template | A generic function that works with different data types |
Key Takeaways
- Functions in C++ make code modular, reusable, and manageable.
- Functions can be parameterized with default values, overloaded with different parameter types, and templated for generic programming.
- Passing by value keeps the original value safe, whereas passing by reference or pointer allows modifying the original variable.
- Lambda expressions offer inline, anonymous functions that can be handy for small operations, especially with STL algorithms.
- Templates and recursion add flexibility to functions, making them adaptable for a wide range of scenarios.