/*---------------------------------------------------------------
                               varg

Programma  che  richiama  una funzione con un numero variabile di
parametri. I parametri in numero variabile  devono  essere  tutti
dello  stesso  tipo  e  devono  essere gli ultimi della chiamata.
Nell'esempio proposto gli argomenti  in numero variabile sono co-
stituiti da  una  struttura composta da una parte numerica ed una
alfabetica. La funzione che li riceve crea una struttura  in  cui
la parte numerica e' la somma dei numeri mentre quella alfabetica
e' la concatenazione  delle  stringhe.  Si  assume  che  l'ultimo
parametro variabile abbia la parte numerica pari a zero.

E' necessario inserire lo header standard stdarg.h. Inoltre nella
funzione con numero variabile di parametri si definisce  un  dato
di tipo va_list.

Il  primo  degli argomenti variabili viene recuperato con la fun-
zione va_start e con l'argomento citato esplicitamente. I succes-
sivi  tramite  la  funzione va_arg, in cui si passa il tipo degli
argomenti.

Alla fine, la  memoria  usata  viene  liberata  tramite  chiamata
alla funzione va_end.

Un esempio  pratico dovrebbe  sperabilmente chiarire le cose.  La
funzione media  viene richiamata con un numero variabile di argo-
menti di tipo double. Tale numero  costituisce il primo argomento
della funzione. Quindi:
  
double media (int n, double a, ...)
{
  va_list ap;
  double  tmp;
  int     i;

  tmp = va_start (ap, a);       // solo il primo
  for (i = n; n > 1; i--)
    tmp += va_arg (ap, double); // dal secondo in poi
  va_end (ap);
  return tmp / (double) n;
}
---------------------------------------------------------------*/

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

#define True  1
#define False !True

typedef struct {char alf[50]; int num;} stru;

int main (void)
{
  int    i;
  stru   array [3], sommastru (stru, ...), tmp; 

  strcpy (array [0].alf, "arco");
  strcpy (array [1].alf, "baleno");
  array [0].num = 1;
  array [1].num = 0;
  printf ("\tdati di partenza\n");
  for (i = 0; i < 2; i++)
    printf ("parte num. %d; parte alf. %s\n", array [i].num, array [i].alf);
  tmp = sommastru (array [0], array [1]);
  printf ("\tsomma\n");
  printf ("parte num. %d - parte alf. %s\n", tmp.num, tmp.alf);

  strcpy (array [0].alf, "Dudel");
  strcpy (array [1].alf, "sack");
  strcpy (array [2].alf, "pfeifer");
  array [0].num = 1;
  array [1].num = 2;
  array [2].num = 0;
  printf ("\tdati di partenza\n");
  for (i = 0; i < 3; i++)
    printf ("parte num. %d; parte alf. %s\n", array [i].num, array [i].alf);
  tmp = sommastru (array [0], array [1], array [2]);
  printf ("\tsomma\n");
  printf ("parte num. %d - parte alf. %s\n", tmp.num, tmp.alf);
  exit (EXIT_SUCCESS);
}

stru sommastru (stru a, ...)
{
  int        count = 0, fine = True;
  stru       r, tmp;
  va_list    ap;

  r.num = 0;
  memset (r.alf, (int) NULL, sizeof r.alf);
  do
    {
      if (count++)
        {
          tmp = va_arg (ap, stru);
          strcat (r.alf, tmp.alf);
          r.num += tmp.num;
          if (! tmp.num) 
            fine = False;
        }
      else
        {
          va_start (ap, a);
          strcpy (r.alf, a.alf);
          r.num += a.num;
          if (! a.num) 
            fine = False;
        }
    }
  while (fine == True);
  va_end (ap);
  return r;
}