Skip to content

Instantly share code, notes, and snippets.

@tlkahn
Forked from hosaka/README.md
Created June 17, 2016 22:21
Show Gist options
  • Save tlkahn/f546ab40836106a23f5787b9b75ef44e to your computer and use it in GitHub Desktop.
Save tlkahn/f546ab40836106a23f5787b9b75ef44e to your computer and use it in GitHub Desktop.
Abstract Data Type using opaque pointers in C
#include <stdio.h>
#include <stdlib.h>
#include "array_api.h"
// abstract array data type types
// opaque pointer:
// an ADT implementation hidden behind the interface that is abstract to
// the client, making it easier to maintain, apply changes and improve
// in this example the array_t data type provides a bunch of functins
// for manipulating the array, these are accessed through the array.h
// interface but the implementation stays hidded in array.c
int main(int argc, char const *argv[])
{
// a solid structure can not be difined because the compiler doesn't know
// how big the data type is since we didn't add any elements to it
// array_t new_array;
// 12:11: error: storage size of ‘new_array’ isn’t known
// we can however define a pointer to such structure because a pointer is
// always of a known size
array_t *arr;
// create a new abstract array with size 3
arr = array_alloc(3);
// set some values
array_set(arr, 0, 1);
array_set(arr, 1, 2);
array_set(arr, 2, 4);
// display the array
array_print(array_begin(arr), array_end(arr));
// cause the array to grow by setting new indecies
array_set(arr, 3, 8);
array_set(arr, 6, 64);
// display the array, note the empty indecies at 4 and 5
array_print(array_begin(arr), array_end(arr));
// free up the array
array_free(arr);
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
// note the absence of array_api.h header
// the array.h is used only in adt.c which needs to know of the interface for
// the ADT this whole file can be a standalone implementation of the data type
// this file can, of course, have it's own header file with function protos
// and other junk, but the array_api.h can stays separate
// abstract data type implementation //
typedef struct array_s
{
int m_size;
int m_capacity;
int * m_data; // actual array data
} array_t;
// memory management
array_t *array_alloc(int size)
{
// memory for the return structure
array_t* ret = malloc(sizeof(array_t));
// size and capacity
ret->m_size = ret->m_capacity = size;
// array data allocation
ret->m_data = malloc(ret->m_capacity * sizeof(int));
return ret;
}
void array_free(array_t *arr)
{
// free array data and struct itself
free(arr->m_data);
free(arr);
}
// manipulations
void array_set(array_t *arr, int index, int value)
{
// set the size if requested index is bigger than we have
if (index >= arr->m_size)
{
arr->m_size = index + 1;
}
// check the capacity
if (arr->m_size >= arr->m_capacity)
{
int new_capacity = arr->m_capacity * 1.5; // why 1.5?
if (new_capacity <= arr->m_size)
{
new_capacity = arr->m_size + 1;
}
// realloc more memory
arr->m_data = realloc(arr->m_data, new_capacity * sizeof(int));
arr->m_capacity = new_capacity;
}
// set the value
arr->m_data[index] = value;
}
void array_print(int *begin, int *end)
{
while (begin != end)
{
printf("%d ", *begin);
begin++;
}
}
// array status info
int *array_begin(const array_t *arr)
{
return arr->m_data;
}
int *array_end(const array_t *arr)
{
return arr->m_data + arr->m_size;
}
#ifndef ARRAY_H
#define ARRAY_H
// Abstract Data Type
//
// This demonstrates information hiding (encapsulation) using C
// If the declaration of array_t or the internal structure were to change
// it would be unnecessary to recompile other modules, unless the API was also
// changed
// object of an incomplete type, why works with or without *?
typedef struct array_s *array_t;
// interface for the ADT
array_t *array_alloc(int size);
void array_free(array_t *arr);
void array_set(array_t *arr, int index, int value);
int *array_begin(array_t *arr);
int *array_end(array_t *arr);
void array_print(int *begin, int *end);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment