Can we pass a function to a function in C as a parameter?
Tags: c, programming, linux, cpp
Published: 2022-07-31 12:01:00

Whenever we work in high-level languages like python and JavaScript we can pass functions as parameters to a function and call it there, But is this also possible in low-level languages like C/C++?

Yes! This is also possible in C/C++ but in a little different way. We know that In C/C++ we have access to memory addresses by pointers. So using a pointer we can also point to a function the same as we do for `array`, `int`, `char`, or any other data type.

So let's start with a very simple program

**Code**

```c
#include<stdio.h>

int add(int a, int b) {
    return a+b;
}

//                  function as param
//                ___________^_____________
int do_operation(int (* operation)(int, int), int a, int b) {
    return operation(a, b);
}

int main(int argc, char const *argv[])
{
    printf("%d\n", do_operation(add, 10, 20));
    return 0;
}
```

**Output**

```bash
30
```

## What's going on in function `do_operation` in the above code?

The parameter `int (* operation)(int, int)` is the function signature with the name `operation`. Let me explain more about it.

```
  int  (* operation) (int, int)
   ^          ^         ^
  left    identifier   right
```

- identifier: function name (operation)
- left: function return type (int)
- right: params type function accept (int, int)

So we can declare a function like this:

```
return_type (* function_name) (param1, param2);
```

## But what if we have to use this function in multiple functions? We will have to declare it like this everywhere?

No. Here comes our life saver `typedef`. We can `typedef` the function signature and use it anywhere. For example, we can declare our above function signature as:

```c
typedef int (* operation)(int, int);

int do_operation(operation op, int a, int b) {
    return op(a, b);
}
```

Isn't this very simple and readable?

![YES](https://img.freepik.com/free-photo/portrait-satisfied-businessman_171337-181.jpg?w=1060&t=st=1659250656~exp=1659251256~hmac=03ee7e8de35a1735bf91ab1cd44cfcaa6dd9dbc95c37d854de30831ec7daecf9)
<figcaption>Source: freepik.com</figcaption >

---

Now Let's take a complex example of how passing functions as parameters can be useful.


**Code**

```c
#include <stdio.h>


/**
 * Defining internal functions
*/
int _multiply(int a, int b) {
    return a*b;
}

int _subtract(int a, int b) {
    return a-b;
}

int _add(int a, int b) {
    return a+b;
}


// Functions name
typedef enum {
    ADD, SUBTRACT, MULTIPLY
} Operations;

// declaring function type
typedef int (*function_t)(int, int);

// struct to hold multiple functions
typedef struct {
    Operations op;
    char name[31];
    function_t fun;
} Operation_t;

// Initialize functions array
Operation_t operations[] = {
    {ADD, "Add", _add}, 
    {SUBTRACT, "Subtract", _subtract}, 
    {MULTIPLY, "Multiply", _multiply}
};

/**
 * Function to do multiple operating by just function name
*/
void do_operation(Operations op, int a, int b) {
    for (int i=0; i<sizeof(operations)/sizeof(Operation_t); i++) {
        if (op == operations[i].op) {
            printf("Operation: %s\n", operations[i].name);
            printf("Result: %d\n\n", operations[i].fun(a, b));
            return;
        }
    }

    printf("Invalid Operation\n");
}


int main() {
    // calling the with function name to perform operation
    do_operation(ADD, 10, 20);
    do_operation(SUBTRACT, 10, 20);
    do_operation(MULTIPLY, 10, 20);
    return 0;
}
```

**Output**

```
Operation: Add
Result: 30

Operation: Subtract
Result: -10

Operation: Multiply
Result: 200
```

From the above code, We can observe that just by passing the function name we can execute it.

---

> This article is highly inspired by the content provided by **Jacob Sorber** on his [youtube channel](https://www.youtube.com/c/JacobSorber).

❤️Thank you so much for reading this article. I'm a passionate engineering student learning new things so If you find any mistakes or have any suggestions please let me know in the comments.

Also, consider sharing and giving a thumbs up If this post helps you in any way.