Loop over multiple arrays simultaneously/C-Elaboration

From Rosetta Code
#include <stdio.h>

typedef struct closure {
    void (*f)( void *elem, void *data);
    void  *data;
} *Closure;
        
typedef struct listSpec{
    void (*print)(const void *);
    void *ary;
    int  count;
    size_t elem_size;
} *ListSpec;

#define LIST_SPEC( pf,typ,aa) {pf, aa, (sizeof(aa)/sizeof(typ)), sizeof(typ) }


/* calls closure's function f for each element in list */
void DoForEach( Closure c, ListSpec aspec )
{
    int i;
    void *val_ptr;
    for (i=0, val_ptr=aspec->ary; i< aspec->count; i++) {
        (*c->f)(val_ptr, c->data);
         val_ptr = ((char *)val_ptr) + aspec->elem_size;
    }
}

/* Used to find the minimum array length of list of lists */
void FindMin( ListSpec *paspec, int *minCount )
{
    ListSpec aspec = *paspec;
    if (*minCount>aspec->count) *minCount = aspec->count;
}

/* prints an element of a list using the list's print function */
void PrintElement( ListSpec *paspec, int *indx )
{
    ListSpec aspec = *paspec;
    (*aspec->print)( ((char*)aspec->ary) + (*indx)*aspec->elem_size);
}


/* Loop Over multiple lists (a list of lists)*/
void LoopMultiple( ListSpec arrays)
{
    int indx;
    int minCount = 100000;
    struct closure c1 = { &FindMin, &minCount };
    struct closure xclsr = { &PrintElement, &indx };
    DoForEach( &c1, arrays);
    printf("min count = %d\n", minCount);

    for (indx=0; indx<minCount; indx++) {
        DoForEach(&xclsr, arrays );
        printf("\n");
    }
}

/* Defining our Lists */

void PrintInt(const int *ival)
{  printf("%3d,", *ival);
}
int ary1[] = { 6,5,4,9,8,7 };
struct listSpec lspec1 = LIST_SPEC( &PrintInt, int, ary1 );

void PrintShort(const short *ival)
{  printf("%3d,", *ival);
}
short ary2[] = { 3, 66, 20, 15, 7, 22, 10 };
struct listSpec lspec2 = LIST_SPEC( &PrintShort , short, ary2 );

void PrintStrg(const char *const *strg )
{  printf(" %s", *strg);
}
const char *ary3[] = {"Hello", "all", "you","good", "folks","out", "there" };
struct listSpec lspec3 = LIST_SPEC( &PrintStrg , const char *, ary3 );

void PrintLstSpec(const ListSpec *ls)
{  printf("not-implemented");
}
ListSpec listList[] = { &lspec1, &lspec2,  &lspec3 };
struct listSpec llSpec = LIST_SPEC(&PrintLstSpec, ListSpec, listList);

int main(int argc, char *argv[])
{
    LoopMultiple( &llSpec);
    return 0;
}