#include <stdio.h>

typedef struct MISC
{
 int tag;         /*Tagwert siehe enum*/
 void *obj;        /*Adresse des Objektes*/ 
 int (*func)();    /*Adresse der Funktion die Ausgeführt wird*/
}MISC;

 /*Kennung :
  ZS_TAG für Zeichen&Sring | SL_TAG für String&Long
  DSD_Tag für Double&String&Double | IS_TAG für Integer&String*/
enum{INVALID_TAG,ZS_TAG,SL_TAG,DSD_TAG,IS_TAG}TAG;

 /*ZS für Zeichen & String*/
typedef struct ZS
{
 char data;
 char zs[80];
}ZS;

 /*SL für String & Long*/
typedef struct SL
{
 char sl[80];
 long data;
}SL;

 /*DSD für Double & String & Dounble*/
typedef struct DSD
{
 double data_a;
 char dsd[80];
 double data_b;
}DSD;

 /*IS für Integer & String*/
typedef struct IS
{
 int data;
 char is[80];
}IS;

 /*Packt verschieden Datenobjekte zusammen.
  MISC *bag -> Struktur unseres Datenobjektes
  int nr    -> Indexzähler für gemischtes Array
  int Tag   -> Tagkennung (siehe enum)
  void *adress -> Adresse des gemischten Objektes
  int (*function)() -> Adresse der Funktion */
void pack(MISC *bag, int nr, int Tag, void *adress, int (*function)())
{
 bag[nr].tag = Tag;
 bag[nr].obj = adress;
 bag[nr].func = function;
}

int zs(ZS *char_string)
{
 printf("Funktion für Zeichen und String aufgerufen\n");
 printf("Zeichen : %c , String : %s\n",char_string->data,char_string->zs);
 return 0;
}

int sl(SL *str_long)
{
 printf("Funktion für String und Long aufgerufen\n");
 printf("String : %s , Long : %d\n",str_long->sl,str_long->data);
 return 0;
}

int dsd(DSD *dstrd)
{
 printf("Funktion für Double String Double aufgerufen\n");
 printf("Double : %f , String : %s , Double : %f\n",
         dstrd->data_a,dstrd->dsd,dstrd->data_b);
 return 0;
}

int is(IS *intstr)
{
 printf("Funktion für Integer und String aufgerufen\n");
 printf("Integer : %d , String : %s\n",intstr->data,intstr->is);
 return 0;
}

int dummy()
{
  return 0;
}


int main()
{
 ZS za = {'x', "String für ZS" };
 SL sa = {"String für SL" , 123456 };
 DSD da = {1.2345, "String für DSD", 6.54321};
 IS  ia = {55 , "String für IS"};
 int (*tag_func[])() = {dummy,zs,sl,dsd,is};

 MISC Pack[4] ={0};
 int i;

 pack(Pack, 0, ZS_TAG, &za,  tag_func[ZS_TAG]);
 pack(Pack, 1, SL_TAG, &sa,  tag_func[SL_TAG]);
 pack(Pack, 2, DSD_TAG,&da,  tag_func[DSD_TAG]);
 pack(Pack, 3, IS_TAG, &ia,  tag_func[IS_TAG]);

 for(i=0; i<4; i++)
   (*Pack[i].func)(Pack[i].obj);
 return 0;
} 

