Functii cu numar variabil de argumente

In anumite situatii nu se pot cunoaste de la inceput numarul de variabile ale unui functii. Insa se cunoaste modul in care se structureaza lista de variabile cu lungime variabila. Un exemplu de acest tip sunt functiile din familia printf. Pentru a veni in sprijinul programatorilor in astfel de situatii a foast creata biblioteca <stdarg.h>. Aceasta introduce un tip de variabila numit va_list si trei functii macro: va_start, va_arg si va_end. Lista de argumente a functiei incepe cu o parte fixa si pentru restul variabilelor se foloseste operatorul (...), ca in exemplul de mai jos. Din argumentele ce constituie partea fixa a listei, sau din modul de proiectare se cunoaste tipul variabilelor nespecificate in lista. Pentru extragerea restului de variabile trebuiesc indepliniti urmatorii pasi:

  1. Trebuie declarata o variabila de tipul va_list, de regula se noteaza cu ap ca in exemplul urmator.
  2. Se apeleaza functia va_start avand ca parametrii ap si ultima varibila din partea fixa a listei (msg in exemplul de mai jos).
  3. Se extrag pe rand valorile variabilele din parte variabila a listei folosind functia va_arg cu parametrii ap si tipul variabilei respective (int in exemplu).
  4. Dupa extragerea tuturor valorilor din lista se apeleaza (inainte de iesirea din functie) functia va_end avand ap drept parametru.

Exemplul 1 (var_arg0.c)

In acest exemplu se calculeaza suma unei secvente de numere intregi (terminata cu 0) folosing o functie cu lista de argumente de lungime variabila.

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

/* calculeaza suma listei de intregi terminata cu 0 */
void sum(char *msg, char *msg1, ...)
{
   int total = 0;
   va_list ap;
   int arg;
   va_start(ap, msg1);
   printf("%s ",msg);
   while ((arg = va_arg(ap,int)) != 0) {
      printf("%d+",arg);
      total += arg;
   }
   printf("0 %s %d\n", msg1, total);
   va_end(ap);
}

int main(void) {
   sum("Suma","este", 1,2,3,4,0);
   sum("Totalul","face", 10,20,30,40,0);
   sum("-->","=", 11,22,33,44,55,0);
   return 0;
}
care returneaza la consola text
Suma 1+2+3+4+0 este 10
Totalul 10+20+30+40+0 face 100
--> 11+22+33+44+55+0 = 165

 

Cornel Mironel Niculae, 2003-2004

06-Jan-2004