# Functions and Function Pointers

Since a function pointer is a valid type, we can pass function pointers as arguments to functions and can also return them from functions.

## Passing Function Pointers to Functions

Recall that the syntax for declaring a function ponter is:

``return_type (*ptr_name) (args);``

Where `ptr_name` is the new variable name for a function pointer that returns something of type `return_type` and that takes the argument types described in `args`. We can similarly accept a function pointer as an argument to a function using the same syntax.

For example, consider the following program:

``````#include <stdio.h>

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

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

int times(int a, int b) {
return a * b;
}

int divide(int a, int b) {
return a / b;
}

//op is a function pointer to a function that takes two integer arguments
//and returns an integer result
int doOperation(int (*op)(int, int), int x, int y) {

//calls the function pointed to by op and returns the result
return op(x, y);
}

int main() {
int num1 = 3;
int num2 = 4;

printf("Added result: %d\n", doOperation(plus, num1, num2));
printf("Multiplied result: %d\n", doOperation(times, num1, num2));

return 0;
}``````

The code above will print:

``````Added result: 7
Multiplied result: 12``````

The above example might seem unnecessarily complicated, as we could have directly called `plus` and `times` from `main` and bypassed the `doOperation` function altogether. However, using function pointers as arguments can be very powerful – for example, the `stdlib` library defines a `qsort` function that accepts a comparator function pointer as an argument. This way, we can use the same sorting function to sort in a variety of ways – ascending order, descending order, by length, etc. – by passing in a different comparator function pointer.

## Typedef and Function Pointers

Listing the type of function pointers can be tedious and error-prone. It can be much easier to use `typedef` once to create a new (more simply named) type representing a particular kind of function pointer, and then use the new type name after that. For example, in our math operations program above, we can first create a new type name for our function pointer type:

``typedef int (*function) (int, int);``

This creates a new type called `function` that represents a function pointer to a function that returns an int and takes two int arguments. We can then use the type `function` in our `doOperation` method instead of writing out the argument `int (*op)(int, int)`. Here is the new `doOperation` function:

``````int doOperation(function op, int x, int y) {

//calls the function pointed to by op and returns the result
return op(x, y);
}``````

Note that the type name `function` can be anything – this is just the new type name we happened to pick when using `typedef`.

## Returning Function Pointers from Functions

Returning function pointers from functions is exactly the same idea as returning any other other type from a function. Ideally, we would first use `typedef` to create a new type name for the desired type of function pointer. For example, we could add a new function to our operations example above that returns a pointer to the correct operation function based on a char argument:

``````function getOperation(char c) {
if (c == '+') {
return plus;
}
else if (c == '-') {
return minus;
}
else if (c == '*') {
return times;
}
else {
//will return 'divide' if a non-operation char argument
//is passed

return divide;
}
}``````

Then, we could use our `getOperation` function to get the correct operation based on user input:

``````char op;
int num1, num2;

printf("Enter number op number (no spaces, like 3+2): ");
scanf("%d%c%d", &num1, &op, &num2);

function opResult = getOperation(op);
printf("Result: %d\n", opResult(num1, num2));``````

By saving the correct operation function in `opResult`, we could then call `opResult` (which would call either `plus`, `minus`, `times`, or `divide` based on the value of `op`) to get the result of the operation.