-  Η δυνατότητα χωρισμού ενός προγράμματος σε ανεξάρτητες λειτουργικές
μονάδες επιτρέπει τον ορισμό αφηρημένων οντοτήτων στις οποίες η
πρόσβαση γίνεται μόνο μέσω συναρτήσεων και με συγκεκριμένο τρόπο.
 -  Η χρήση των οντοτήτων αυτών γίνεται μόνο μέσω των συναρτήσεων και
των τύπων που ορίζονται σε αντίστοιχο αρχείο επικεφαλίδων,
ενώ η υλοποίηση γίνεται σε ξεχωριστό αρχείο C.
Ο τρόπος αυτός προγραμματισμού ξεχωρίζει την υλοποίηση από τους μηχανισμούς
πρόσβασης επιτρέποντάς μας να αλλάξουμε την υλοποίηση χωρίς να επηρεαστεί
το υπόλοιπο πρόγραμμα.
 -  Το παρακάτω παράδειγμα ορίζει έναν μετρητή ο οποίος μπορεί
μόνο να αυξάνεται:
/*
 * Header file
 */
extern int get_counter(void);
extern void inc_counter(void);
/*
 * C file
 */
static int counter;
int
get_counter(void)
{
        return (counter);
}
void
inc_counter(void)
{
        counter++;
}
 -  Το παραπάνω παράδειγμα δημιουργεί έναν μόνο μετρητή.
Με τη χρήση δεικτών και δυναμικής μνήμης μπορούμε να ορίσουμε ένα
εργοστάσιο που να δημιουργεί απεριόριστο αριθμό από μετρητές.
Ο αφηρημένος τύπος του μετρητή παριστάνεται ως ένας δείκτης σε
ακέραιο:
/*
 * Header file
 */
typedef int *counter;
extern counter new_counter(void);
extern int get_counter(counter c);
extern void inc_counter(counter c);
/*
 * C file
 */
/*
 * Return a new counter object
 */
counter
new_counter(void)
{
        counter c;
        c = (counter)malloc(sizeof(int));
        *c = 0;
        return (c);
}
int
get_counter(counter c)
{
        return (*c);
}
void
inc_counter(counter c)
{
        (*c)++;
}
 -  Με τη χρήση των παραπάνω αρχείων μπορούμε να προγραμματίσουμε
με δύο λ.χ. μετρητές:
#include <stdio.h>
#include "counter.h"
main()
{
        counter c1, c2;
        c1 = new_counter();
        c2 = new_counter();
        inc_counter(c1);
        inc_counter(c1);
        inc_counter(c2);
        printf("%d %d\n", get_counter(c1), get_counter(c2));
}
 -  Το παραπάνω παράδειγμα επιτρέπει σε κάποιον να διαβάσει στο
αρχείο των επικεφαλίδων ότι ο αφηρημένος τύπος είναι ένας δείκτης
σε ακέραιο και να τον μεταβάλει με λάθος τρόπο (πχ *c = 12;).
Μπορούμε να διασφαλίσουμε τον αφηρημένο τύπο από τέτοιου είδους
προσβάσεις ορίζοντας μια δομή στο αρχείο υλοποίησης
και μόνο έναν δείκτη στη δομή αυτή στο αρχείο επικεφαλίδων
(η γραφή structptr->member είναι συντομογραφία της (*structptr).member):
/*
 * Header file
 */
typedef struct s_counter *counter;
extern counter new_counter(void);
extern int get_counter(counter c);
extern void inc_counter(counter c);
/*
 * C file
 */
struct s_counter {
        int value;
};
/*
 * Return a new counter object
 */
counter
new_counter(void)
{
        counter c;
        c = (counter)malloc(sizeof(struct s_counter));
        c->value = 0;
        return (c);
}
int
get_counter(counter c)
{
        return (c->value);
}
void
inc_counter(counter c)
{
        c->value++;
}
 -  Είναι αξιοσημείωτο ότι η παραπάνω (διαφορετική) υλοποίηση συνεχίζει
να είναι συμβατή με το πρόγραμμα το οποίο χρησιμοποιεί τους δύο δείκτες.