Topics
- Motivation: Real-world examples where functions are useful (e.g. code organization, reusability)
- Functions: Definition, declaration, call
- Parameters: Definition, passing data, default values
- Return values: Definition, return statement
- Default values
- Function Overloading
Functions
Functions organize code into reusable, modular blocks that only execute when called.
Benefits:
- Code organization
- Reusability
- Modularity
- Readability
- Maintainability
void play_music(){
cout << "Playing Music";
}
int main(){
play_music(); // call the function
return 0;
}
Definition: A function is a block of code that executes when βcalledβ.
Declaration: Defines the function name, return type, and parameters.
Definition: Provides the body/logic of the function.
Call: Executes the function code block followed by two parentheses () and a semicolon ;
// Declaration + Definition = Functions
// Declaration
void play_music(){
// Definition/Logic
cout << "Enter your favourite song : ";
int song;
cin >> song:
cout << "Playing song : " << song;
}
// Function Call
play_music();
Forward Declaration
A forward declaration tells the compiler about a function before it is defined. This allows you to call the function before defining it.
Why use forward declarations?
- It allows you to declare functions in any order, instead of having to define a function before calling it. This improves code organization.
- It avoids ordering dependencies and circular dependencies between functions that call each other.
Example:
#include<iostream>
using namespace std;
// Forward Declaration
void playMusic();
int main(){
playMusic();
return 0;
}
// This will give compile time error untill unless Forward declaration is not there
void playMusic(){
cout << "Playing Music";
}
Without the forward declaration above main()
, the code would fail to compile due to playMusic()
not being defined at the point it is called.
Some key points:
The declaration only needs the function name, parameters, and return type.
You can put the full definition anywhere later.
This relaxes restrictions on ordering compared to no forward declaration.
NOTE
Compilation happen from Top-to-Bottom of a code. Execution happen for the main() block of the code.
Parameters
Parameters allow passing data into a function.
Why Use Parameters?
- It enables code reusability - same function can be used for different values
- It allows making functions more dynamic and configurable
- Eliminates need for global variables to pass data
Passing Data through βParameters β
You can pass data, known as parameters, into a function. Parameters act as variables inside the function. You can add as many parameters as you want, just separate them into a comma.
void play_music(int song_id){ // int song_id is a parameter
cout << "Playing song" << song_id;
}
int main(){
play_music(5);
return 0;
}
#include<iostream>
using namespace std;
void playMusic(int songID, float Duration){ // int songID is a parameter
cout << "Playing Song " << songID << " for" << Duration << " minutes" << endl;
}
int main(){
playMusic(1, 5.00); // value 1, 5.00 is an argument
playMusic(2, 3.21);
playMusic(3, 3);
return 0;
}
Default Values of Parameters
You can also set default parameter values that are used if no argument is passed, by using the equal sign (=). If we call the function without an argument, it uses the default value.
// default value parameters should come after parameters with no-default
void play_music(int song1=1, int song2=2, int song3 =3){
cout << "Playing Song " << song1 << song2 << song3 << endl;
}
int main(){
play_music(5);
return 0;
}
Return Values
If you want the function to return
a value, you can use a data type (such as int
, string
, etc.) instead of void
, and use the return keyword inside the function.
bool login(String username){
// some logic
return true;
}
int countFriends(){
// some logic
return 5;
}
void play_music(int song1=1, int song2=2, intsong3=3){
cout << "Playing song " << song1 << song2 << song3;
}
Functions can also return some data back to the place from where they are called using a return
keyword and specifying a return type.
The void keyword used in the below examples, indicates that the function should not return a value.
void play_music(int song1=1, int song2=2, intsong3=3){
cout << "Playing song " << song1 << song2 << song3;
}
Example:
#include<iostream>
using namespace std;
int multiply(int a, int b) {
int result = a * b;
return result;
}
int main() {
int x = 5, y = 3;
int product = multiply(x, y);
cout << "Product is: " << product; // Prints 15
}
Some key points:
- T- Return type ofΒ
main()
Β should beΒint
Β instead ofΒvoid
Β to return exit status code.- Return values can be ignored if not required by calling code.
Function Example - Factorial
Letβs look at an example function that calculates the factorial of a number.
The factorial of a number N is defined as:
Factorial(N) = 1 x 2 x 3 x ... x N
For example:
Factorial(5) = 1 x 2 x 3 x 4 x 5 = 120
Here is how we can write a factorial function:
#include<iostream>
using namespace std;
// Function declaration
int factorial(int N);
int main() {
int num;
cin >> num;
// Function call
int result = factorial(num);
cout << "The factorial of " << num << " is " << result << endl;
return 0;
}
// Function definition
int factorial(int N) {
int factorial = 1;
for(int i=1; i<=N; i++) {
factorial *= i; // factorial = factorial * i
}
return factorial;
}
Explanation:
- We first declare the function prototype before
main()
. - We get user input and call
factorial()
in main(). - The factorial() function:
- InitializesΒ
factorial = 1
- Runs a loop calculating the product from 1 to N
- Returns the factorial values
- InitializesΒ
- We print the final factorial value in
main()
This demonstrates how we can break logic into reusable functions that can be called from anywhere inside code.
Function Overloading
Function overloading allows creating multiple functions with the same name but different parameters.
Why Use Function Overloading?
- It improves code readability by using the same function name to represent similar operations.
- You donβt have to remember different function names that essentially do the same thing.
- It eliminates naming conflicts.
Ways to Overload a Function
There are two main ways to overload functions:
- By using different data types for parameters
void print(int x) {
// Print int
}
void print(double x) {
// Print double
}
void print(char* x) {
// Print string
}
- By using a different number of arguments
int sum(int x, int y) {
return x + y;
}
int sum(int x, int y, int z) {
return x + y + z;
}
Functions Overloading - using Variable parameters
#include<iostream>
using namespace std;
// Functtion Overloading Demo -> Multiple Functions, same name
int area(int l, int b){
return l*b;
}
int area(int l){
return l*l;
}
int main(){
cout << area(5) << endl;
cout << area(5,3) << endl;
return 0;
}
Function Overloading Datatypes
#include<iostream>
#include<vector>
using namespace std;
// Functtion Overloading Demo -> Multiple Functions, same name
// Create a Print function that accepts different types if datatypes
void print(int a){
cout << a << endl;
}
void print(vector<int> a){
for(int x : a){
cout << " , ";
}
cout << endl;
}
void print(char *arr){
cout << arr << endl;
}
int main(){
int a = 5;
vector<in> arr = {1,2,3,4,5};
char carr[] = "abcd" // after the last " it will hit the null
print(a);
print(arr);
print(carr);
return 0;
}
/* Output:
5
1, 2, 3, 4, 5
abcd
*/