An abstract data type is a struct, whose definition is not exposed to the user.
This is useful for a couple of different reasons
To define an ADT we typedef our struct definition.
typedef OLD_TYPE ALIAS;
For example, typedef struct Person Person.
This will make Person an alias of struct person.
By doing so, we have successfully abstracted the Person type. We would use Person for future uses.
Person p = { ... };
As it is very common to pass data by reference, it is recommended to make ADT definitions a pointer.
typedef struct Person *Person;
This way whenever we use Person, we are defining a pointer to a struct Person.
To make an ADT truly abstract, we want to put all ADT code in their own .h header and .c source files.
Person.h
#ifndef _PERSON_H_
#define _PERSON_H_
typedef struct Person *Person; // Define Person as a pointer
#endif // to a struct Person
Person.c
struct Person {
char* name;
int age;
char* address;
};
We put the function prototypes in the .h header, and implementation in the .c source.
/* Person.h */
typedef struct Person *Person;
char *get_name(Person p);
int get_age(Person p);
/* Person.c */
#include <string.h>
char *get_name(struct Person *p) {
return (p == NULL || p->name == NULL)
? NULL : strdup(p->name0);
}
int get_age(struct Person *p) {
return p->age;
}
Without knowing the content of the .c source file, we can use the functions declared in the header.
/* Person.h */ typedef struct Person *Person; char *get_name(Person p); int get_age(Person p);
#include <Person.h>
int main(void) {
Person p = ...;
printf("Age: %d\n", get_age(p));
}