C. For each function independent of data types

При работе на C часто имеешь дело с массивами разного типа. Для вывода содержимого каждой из них нужно реализовать собственные функции. Учитывая, что перегрузка в данном случае не поддерживается, нужно еще и разные имена придумать. Всем известна функция qsort

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

которая может работать с массивами абсолютно разного типа. Можно ли реализовать аналогичную универсальную функцию для вывода содержимого массивов так же независимо от типа.  Ниже приведен один из подходов.

#include <stdio.h>
#include <string.h>

#define count(x) sizeof(x) / sizeof(x[0])

typedef struct {
  int id;
  char title[50];
  char author[50];
  char subject[50];
} Book;

void for_each(void *base, size_t num, size_t size, void (*by_item) (void *)) {
  unsigned char *p = (unsigned char *) base;
  unsigned int i = 0;
  for (; i < num; i++) {
    by_item(p + i * size);
  }
}

// show int item
void show_num(void *item) {
  printf("item = %d\n", *((int *) item));
}

// show char item
void show_char(void *item) {
  printf("item = %c\n", *((char *) item));
}

// show Book item
void show_book(void *item) {
  printf("id:%d title:%s author:%s subject:%s\n", 

                   ((Book *) item)->id, 
                        ((Book *) item)->title, 
                              ((Book *) item)->author, 
                                    ((Book *) item)->subject);
}

int main() {
  int nums[] = {1, 2, 3, 4, 5};
  char chars[] = "abcdefgh";
  Book books[] = {
    {11179, "Book_1", "Jon Bredbery", "Tutorial_1"},
    {34454, "Book_2", "Adam Rich", "Tutorial_2"},
    {76899, "Book_3", "Den Swarovsky", "Tutorial_3"}
  };

  for_each(nums, count(nums), sizeof(int), show_num);//show all nums
  for_each(chars, strlen(chars), sizeof(char), show_char);//show all chars
  for_each(books, count(books), sizeof(Book), show_book);//show all books

  return 0;
}