A 1.10.2-es részben ismertetett printf, illetve scanf függvények (függvénycsaládok) tipikus példái a változó paraméterlistájú függvényeknek. A továbbiakban a printf függvény egy minimál implementációján keresztül mutatjuk be, hogyan készíthetünk portábilis, változó hosszúságú paraméterlistával rendelkezõ C függvényeket. Függvényünket a következõképpen deklaráljuk:
void minprintf(const char *fmt, ...);Azért void típusú a függvény, mert az egyszerûség kedvéért ebben a példában a konvertált adatok számával nem foglakozunk, így azt visszatérési értékül sem tudjuk szolgáltatni. A deklarációban a ... csak a formális paraméterlista utolsó elemeként szerepelhet, és legalább egy megnevezett argumentumot kell deklarálnunk ahhoz, hogy a változó hosszúságú paraméterlistát majd kezelni tudjuk.
A szabványos stdarg.h include file tartalmazza azokat a makrókat, amelyek a változó hosszúságú paraméterlisták kezeléséhez szükségesek. Az egyes makrók megvalósítása géprõl gépre változhat, de a makrók egységes felületet teremtenek a pobléma kezeléséhez.
A va_list típus szolgál arra, hogy a soronkövetkezõ függvényargumentumra vonatkozó információ tárolására való változót - egy argumentum-pointert - deklarálhassunk. A va_start( ) makróval inicializálhatunk egy ilyen változót. Az inicializálás eredményeképpen az argumentum-pointer az elsõ azonosító nélküli argumentumra fog mutatni. Mint említettük, legalább egy azonosítóval rendelkezõ elemet kell hogy tartalmazzon a formális paraméterlista. Ezt használja fel a va_start( ) makró az argumentum pointer inicializálásához. A va_arg( ) makróval léphetünk tovább a következõ azonosító nélküli argumentumra. Ez a makró a soron következõ aktuális paramétert szolgáltatja értékül. Ennek a makrónak két paramétere van. Az elsõ az argumentum-pointer, a második pedig egy típusazonosító, amely megszabja, hogy milyen legyen a visszatérési érték típusa, és hogy az argumentum-pointert milyen mértékben (hány byte-tal) kell továbbléptetni. A va_end( ) makró szolgál arra, hogy "rendet rakjon" egy változó hosszúságú paraméterlistával rendelkezõ függvénybõl való visszatérés elõtt. Ezt a makrót mindig meg kell hívni egy ilyen függvénybõl való kilépés alkalmával.
Ezek után nézzük meg az egyszerüsített printf függvény listáját!
#include <stdarg.h>
/************************************************************/
void minprintf(const char *fmt, ...)
/* */
/* Valtozo hosszusagu parameterlista kezelesenek bemutatasa */
/* a minimalis printf funkciok kapcsan. Mezoszelesseg, stb. */
/* kimarad, konverzio es nyomtatas az eredeti printf-fel. */
/************************************************************/
{ va_list ap; /* argumentum pointer */
char *p, /* fmt-n szalad majd vegig */
*sval; /* ->sztring tipusu parameter erteke */
int ival; /* int tipusu parameter erteke */
double dval; /* double tipusu parameter erteke */
va_start(ap, fmt); /* ap az fmt utani elso arg.-ra mutat */
for (p = fmt, *p, p++) /* p-t EOS-ig lepteti */
{ if (*p != '%') { putchar(*p); } /* Csak masolas */
else /* specifikacio feldolgozasa: */
{ switch(*++p)
{
case 'd': ival = va_arg(ap, int);
printf("%d", ival);
break;
case 'f': dval = va_arg(ap, double);
printf("%f", dval);
break;
case 's': for(sval = va_arg(ap,char*); *sval; sval++)
{
putchar(*sval);
}
break;
default: putchar(*p);
break;
}
}
}
va_end(ap); /* Takaritas a fuggveny vegen */
}
/************************************************************/