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
#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
#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
counter_add(c, ____);
counter_add(c, 5);
Explanation: counter_add(c, 5); adds 5 to the counter.