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
  • 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:

  1. 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   
}   
  1. 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
*/