C function to print arrays of arbitrary data type
First of all this is a good attempt to provide polymorphism for print functionality. Few comments that might help:

I studied the print_array function and we can certainly do few improvements to it.

1) int print_array(const void *array, size_t length, char *type) 

The type parameter is defined as char *. Since this function will support only a predefined types its better to have those as enum values. for e.g. you could do a typedef as 

typedef enum{
INT = 0,
DOUBLE,

MAX_TYPES,
}SUPPORTED_TYPES;


2) if (!strcmp(type, TYPE_INT)) 
We can avoid these comparisons by making use of a Map like feature. Your current approach requires changing print_array function for any new type that we add. For e.g. tomorrow if you add support for print_char you will have to make those changes in print_array as well. Wouldn't it be better if print_array required no change. Ok so how to do it. In C++ there is a rule to replace conditional statements with polymorphism or maps. We will use maps here.

Since we already changed the type to an enum we can define a new struct which holds what functions to call for what data-types and the size of data-type as below:

typedef struct{
    void (*function)(const void *number);
    int size_of_elements;
}FunctionMap;


Now we create a mapping for data-types to function and store it in a global variable say print_map

const FunctionMap print_map[] = {
    [INT] = {print_int,sizeof(int)},
    [DOUBLE] = {print_double,sizeof(double)},
};


Now your print_array function changes just to few lines i.e. a lookup into this print_map for the type that is passed.

int print_array(const void *array, size_t length, SUPPORTED_TYPES type) 
{

    assert(type&lt;MAX_SUPPORTED);
    assert((sizeof(print_map)/sizeof(FunctionMap)) == MAX_SUPPORTED);

    void (*function)(const void *number);
    const void *cast_array = array;
    size_t size;
    size_t i;
    function = print_map[type].function;
    size = print_map[type].size_of_elements;
    for (i = 0; i &lt; length; ++i) {
        function(cast_array + i * size);
    }
    printf("\n");
    return 0;
}


Note that I have added few asserts to make sure that the user passes proper values for type and that the implementer has add all data-type mappings in print_map. Now whenever you define a new print type say print_char you don't need to change print_array. Just add that function and its mapping in print_map and everything should work as it is.

Hope this helps.