Práca so
zoznamom argumentov

Funkcie s premenlivým počtom argumenov

Hneď na začiatok klasický príklad - funkcia printf. Môže do nej vstupovať reťazec, alebo reťazec a ďalšie argumenty, a to dokonca argumenty rôznych typov a aj tak to celé pekne funguje :)
Pomocou pretypovania, príp. pomocou implicitných argumentov funkcie, sa dá celkom pekne vytvoriť funkcia, ktorej počet parametrov nie je dopredu definovaný. Určité funkcie sa však takto pekne urobiť nedajú. Povedzme, že chceme funkciu, ktorá bude vracať priemer čísel, ktoré do nej vstúpia. Nenapadá ma v tejto chvíli možnosť ako to urobiť pomocou implicitných argumentov, a napísať n preťažených funkcií tiež nie je najšťastnejšie riešenie, najmä ak bude niekto chcieť do funkcie poslať n+1 argumentov :)
#include "stdio.h"
#include "stdarg.h"

double average(int n, ...){
va_list arg;
int suma=0;
int pocet=n;

va_start(arg,n);
while (n--)
   suma+=va_arg(arg,int);
va_end(arg);
return ((double)suma/pocet);
}

void printf (int a){
  printf("\n%d",a);   }

int main(int argc, char* argv[])
{

printf("%f", average(3,   4,3,9));

char pause=getchar();

        return 0;
}
Prvým parametrom funkcie average, je počet čísel, z ktorých chcem urobiť priemer, ďalšie parametre sú jednotlivé čísla...
Funkcia va_start (čo nie je funkcia, ale makro, avšak to je úplne jedno teraz) nastavuje jej prvý argument (ktorý je špeciálneho typu va_list) na prvý z možných argumentov, ktoré vstupujú do funkcie. Ako keby nastaví ukazovateľ na prvý prvok.
Keď potom zavolám funkciu va_arg, tak tá mi vyextrahuje konkrétny argument a zväčší smerník o jedna. Ak zavolám va_arg znova, ona mi vráti nasledujúci argument...
No a nakoniec treba volať funkciu va_end, ktorá korektne ukončí celé toto úsilie s premenlivým počtom argumentov...
Celé je to síce na pohľad pekné, ale akonáhle sa tým začnem zaoberať hlbšie už mi to tak pekné nepríde.
Prvá nevýhoda je, že funkcii treba dať nejak vedieť koľko parametrov do nej vstupuje, alebo aspoň aký je posledný parameter (aby vedela dokedy môže extrahovať argumenty). Oveľa krajšia by bola funkcia ktorá robí rovno priemer z čísel čo jej zadám, a netreba jej vravieť koľko argumentov má... (takúto funkciu, zatiaľ bez preťažovania spraviť v tejto chvíli neviem... :)
Ďalšia nevýhoda je, že funkcia nemá ako zistiť, či som jej zadal "správny" typ argumentov. va_arg proste vytiahne s pamäti to o čom si myslí, že je to int, a ak som ja náhodou zadal ako parameter napríklad float, tak žiadny pekný výsledok nemožno očakávať... Rovnako, keď aj zadám iba vhodné argumenty, treba si dávať v rámci tela funkcie pozor dokedy extrahujem, aby som nezačal extrahovať aj to čo neexistuje. Výsledkom by bol opäť nezmysel...
No a posledná nevýhoda je (aspoň pre mňa :) že úplne nerozumiem mechanizmu ako tieto makrá pracujú a tak to zatiaľ neplánujem veľmi používať...

(c) Wray 2006