Passing Functions as Arguments
Part of the Object Oriented Programming section of Coddy's C journey — lesson 36 of 61.
One of the most powerful uses of function pointers is passing them as arguments to other functions. This allows you to inject custom behavior into a function without modifying its code — a technique sometimes called a callback.
Consider a function that performs a calculation on two numbers. Instead of hardcoding the operation, you can accept a function pointer that defines what operation to perform:
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}The compute function doesn't know whether it's adding, subtracting, or doing something else entirely. It simply calls whatever function is passed to it:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Output: 8
printf("%d\n", compute(5, 3, multiply)); // Output: 15
return 0;
}Notice how the same compute function produces different results based on which function we pass. This pattern is fundamental to writing flexible, reusable code — you write the structure once, and users of your function supply the specific logic they need.
Challenge
EasyWrite a function apply_twice that takes two integers and an operation code, applies the operation to the numbers twice in sequence, and returns the final result.
Your function will receive an operation code that determines which operation to use. You must define the operation functions inside your solution and pass them to a helper compute function that accepts a function pointer.
Required structure:
- Define a
typedefcalledOperationfor a function pointer that takes twointparameters and returns anint - Define two operation functions:
add(returns a + b) andmultiply(returns a * b) - Define a
computefunction that takes two integers and anOperationfunction pointer, then returns the result of calling the operation - In
apply_twice, select the appropriate operation based on the code, then usecomputetwice: first with the original numbers, then with the result and the second number again
Logic:
- Select the operation function based on
op_code(1 = add, 2 = multiply) - Call
compute(a, b, operation)to get an intermediate result - Call
compute(intermediate, b, operation)to get the final result - Return the final result
Parameters:
a(int): First numberb(int): Second numberop_code(int): Operation code (1 for add, 2 for multiply)
Returns: The result after applying the operation twice in sequence (int)
Example: With a = 5, b = 3, op_code = 1 (add):
- First compute: 5 + 3 = 8
- Second compute: 8 + 3 = 11
- Return: 11
With a = 2, b = 4, op_code = 2 (multiply):
- First compute: 2 × 4 = 8
- Second compute: 8 × 4 = 32
- Return: 32
Cheat sheet
Function pointers can be passed as arguments to other functions, enabling callbacks — a way to inject custom behavior without modifying the function's code.
Define a function pointer type using typedef:
typedef int (*Operation)(int, int);Create a function that accepts a function pointer as a parameter:
int compute(int a, int b, Operation op) {
return op(a, b);
}Pass different functions to achieve different behaviors:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Output: 8
printf("%d\n", compute(5, 3, multiply)); // Output: 15
return 0;
}This pattern allows you to write flexible, reusable code where the structure is defined once and users supply the specific logic they need.
Try it yourself
int apply_twice(int a, int b, int op_code) {
// Write code here
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box7Function Pointers
Declaring Function PointersCalling Function PointersTypedef for Function PointersPassing Functions as ArgumentsRecap: Calculator Dispatch2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy