CodeBlanks Logo Icon CodeBlanks

Opaque types

  • C course
  • Intermediate
  • Lesson 109/116
  • 5 min

Learn opaque types and information hiding.

Opaque types

An opaque type hides its internal structure from the user. The header file contains only typedef struct Counter Counter;; the definition of struct Counter stays hidden in the source file.

The user holds a Counter * pointer but cannot access its contents. The struct is reached only through functions you provide (counter_new, counter_add, counter_get). This is the core way C achieves abstraction. Because the user does not know the internal layout, you can change it later without breaking user code. This pattern is common in real libraries; for example, the FILE type is opaque.

The Counter opaque type

A Counter opaque type accumulates a value through successive calls. The user sees only three functions: counter_new, counter_add and counter_get.

Example use: Counter *c = counter_new(); counter_add(c, 5); counter_add(c, 3); printf("%d\n", counter_get(c));. The output is 8. The user cannot write c->value because they cannot see the definition of struct Counter. This is a safe interface: only allowed operations can be performed. This pattern is C's equivalent of object-oriented programming; data and the functions that operate on it are packaged together.

Practice Write an opaque Counter

Declare the opaque type with typedef struct Counter Counter;. Add the definition struct Counter { int value; };. Write Counter *counter_new(void), void counter_add(Counter *c, int n) and int counter_get(Counter *c). In main write Counter *c = counter_new(); counter_add(c, 5); counter_add(c, 3); printf("%d\n", counter_get(c)); free(c);.

Starter code

main.c
#include <stdio.h>
#include <stdlib.h>

// Declare Counter as opaque
// Write counter_new, counter_add, counter_get functions
// Use the counter in main and print

int main(void) {
    return 0;
}

Sample solution

main.c
#include <stdio.h>
#include <stdlib.h>

typedef struct Counter Counter;

struct Counter { int value; };

Counter *counter_new(void) {
    Counter *c = malloc(sizeof(Counter));
    c->value = 0;
    return c;
}

void counter_add(Counter *c, int n) {
    c->value += n;
}

int counter_get(Counter *c) {
    return c->value;
}

int main(void) {
    Counter *c = counter_new();
    counter_add(c, 5);
    counter_add(c, 3);
    printf("%d\n", counter_get(c));
    free(c);
    return 0;
}

Expected output

8

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What is the advantage of an opaque type?

  • Internal structure is hidden and can change later Correct answer
  • Automatic memory management
  • Less memory usage
  • Faster compilation

Explanation: An opaque type hides the internal structure; you can change it later without breaking user code.

2 Match the Counter functions

Term Meaning
counter_new New counter
counter_add Add value
counter_get Read value
Counter * Opaque pointer

3 Complete the counter_add call

Question
counter_add(c, ____);
Answer
counter_add(c, 5);

Explanation: counter_add(c, 5); adds 5 to the counter.

All lessons in Intermediate