Pointer
Before diving to function pointer let's recap pointers. A pointer is a variable that points(store) to the address of another variable.
Gameplay of address
Consider a Game to find the treasure. There are a lot of rooms but you won't get the treasure directly until you have the golden paper and address written on it. We searched and found the golden paper is inside room 100. Now following the address we found the treasure 💰. Look at the pictures below.
This might not seem a great game 😊, but the key idea is that a room has (pointing to) the address of another room.
Let's understand the pointer by the same analogy.
room -> variable & room id -> address of variable
int age = 25; // age is normal variable
int *p = &age; // p is pointer variable
// * before p tells p will store address
// '&' gives address of a variable
Let's zoom Inside memory
cout << age;
will print 25, whereas cout << p;
will print 205 (arbitrary address). Your computer will print a different address as actual addresses are in hexadecimal and the same memory might not be free.
Dereferencing the pointer
Now we have two ways to access 25 the first one is age variable and the second is p variable, as p is pointing to age, so we can access age by p indirectly. Accessing age through p is called dereferencing
.
cout << p; // 205
cout << *p; // 25
// p -> 205, *p means whats there where p is pointing.
Basics of Function
Suppose we have to find the maximum of two integers many times in our program, then in spite of writing the logic every time we can write once and use it as many times we want. Also if need to change the logic we'll have to correct it only in a single place.
int findMax(int num1, int num2)
{
if(num1 > num2)
{
return num1;
}
else
{
return num2;
}
}
int max = findMax(8, 15);
cout << max; // 15
Function pointer, address of function definition
Everything in a code requires memory either its variable or function and if it resides inside memory then there is an associated memory address. So a variable that stores the address of a function is a function pointer.
Consider the add function
int add(int x, int y)
{
return x + y;
}
int (*funPtr) (int, int); // prototype of fun whose address will be stored.
funPtr = add; // &add will do same thing
// add , funPtr is pointing to same instructions on memory
Syntax details
Function call through pointer
cout << add(5, 4); // calling add directly
cout << funPtr(5, 4); // calling add indirectly as funPtr is pointing to add
funPtr
can be used to point to any other function whose return type is int and takes two arguments of int type. e.g.
int speed(int dis, int t)
{
if (t == 0)
{
cout << "Denominator can't be zero.";
return -1;
}
return dis / t;
}
funPtr = speed; // & operator can be omitted, funPtr defined in prev code
cout << funPtr(100,20); // 5
Consider another example
void my_fun() {
cout<<"Hello";
}
void (*f)() = my_fun;
Magic with auto keyword
`auto' makes our life easier by omitting the complexities. It translates to the same thing behind the scene by itself.
void my_fun() {
cout<<"Hello";
}
auto fun_ptr = my_fun; // same as void (*fun_ptr)()
Lambda function
A/c to definition lambda function is a small anonymous function and it can take any number of arguments. Since it is anonymous, a function pointer will be required to store the anonymous function. Let's code.
void (*func)() = []()
{ cout << "Lambda function..."; };
// func is a function pointer, anonymous function definition is on the right side of equality.
int (*increaseBy2)(int) = [](int x)
{ return x + 2; };
// calling
func(); // Lambda function... will be printed
cout << increaseBy2(55); // 57
We can also shorten the declaration by the auto
keyword as it will infer the type on its own.
auto add = [](int x, int y)
{ return x + y; };
cout << add(5, 15); // 15
Congrats 🎊, you learned Pointer, Function, and Lambda function.