Menu
Coddy logo textTech

The Interface Concept

Part of the Object Oriented Programming section of Coddy's C journey — lesson 40 of 61.

So far, our structs have mixed data and behavior together — a name alongside a function pointer, for example. But what if a struct contained only function pointers? This creates something powerful: an interface.

An interface defines what operations are available without specifying how they work. It's a contract that says "any object implementing this interface must provide these functions."

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

The ILogger struct contains nothing but a function pointer. It has no data of its own — it purely describes behavior. The "I" prefix is a common convention indicating this is an interface.

Any code that accepts an ILogger doesn't care where the log message goes. It could print to the console, write to a file, or send data over a network. The caller just knows it can call log:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // We don't know HOW it logs
}

This separation is the essence of polymorphism. The process function works with any logger implementation — you can swap behaviors without changing the function's code. In the next lesson, you'll create concrete implementations that fulfill this interface contract.

challenge icon

Challenge

Easy

Let's build a ICalculator interface — a struct that contains only function pointers, defining what operations any calculator must support without specifying how they work.

You'll create two files to organize your code:

  • calculator.h: Define your interface here. Create a function pointer type called BinaryOp that takes two int parameters and returns an int. Then define an ICalculator struct that contains only two function pointers: operate (of type BinaryOp) and describe (a function pointer that takes no parameters and returns nothing). This struct is purely an interface — it holds no data, only behavior.
  • main.c: Include your header and implement concrete functions that can fulfill the interface:
    • add — returns the sum of two integers
    • multiply — returns the product of two integers
    • describe_add — prints Addition
    • describe_multiply — prints Multiplication
    Then create an ICalculator instance, wire it up based on input, and use it to perform a calculation.

Your program will receive three inputs: two integers and an operation code (1 for addition, 2 for multiplication).

Based on the operation code, wire your ICalculator with the appropriate pair of functions. Then call describe through the interface to print the operation name, followed by calling operate to compute and print the result.

Example output when inputs are 5, 3, and 1:

Addition
8

Example output when inputs are 4, 7, and 2:

Multiplication
28

The key insight is that your ICalculator struct defines a contract — any code using it knows it can call describe and operate, without knowing which specific functions are wired in. Remember to use include guards in your header file.

Cheat sheet

An interface is a struct that contains only function pointers, defining what operations are available without specifying how they work.

Defining an interface:

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

The "I" prefix is a common convention indicating this is an interface. The struct contains no data — it purely describes behavior.

Using an interface:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // We don't know HOW it logs
}

This separation enables polymorphism — the function works with any implementation of the interface, allowing you to swap behaviors without changing the function's code.

Try it yourself

#include <stdio.h>
#include "calculator.h"

// TODO: Implement the add function
// Returns the sum of two integers


// TODO: Implement the multiply function
// Returns the product of two integers


// TODO: Implement describe_add function
// Prints "Addition"


// TODO: Implement describe_multiply function
// Prints "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: Create an ICalculator instance
    
    
    // TODO: Based on op_code (1 for add, 2 for multiply),
    // wire the calculator with the appropriate functions
    
    
    // TODO: Call describe through the interface
    
    
    // TODO: Call operate through the interface and print the result
    
    
    return 0;
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming