Przekazywanie do funkcji w C++ n-argumentów
Czasami kiedy piszemy jakąś funkcję tak naprawdę nie wiemy ile będziemy potrzebowali obsłużyć w niej danych. Wiąże się to z pewnym problem gdyż nie możemy po prostu napisać, że dana funkcja przyjmuje 2, 3 albo 4 argumenty. Oczywiście twórcy C++ zwrócili uwagę na ten problem i zaimplementowali specjalny mechanizm umożliwiający odczytywanie n argumentów. Mamy więc możliwość „przesyłania” do danej funkcji praktycznie nieograniczonej liczby danych (jedynym ograniczeniem jest dostępna pamięć operacyjna).
Mamy zwykłą funkcję mnozenie() przyjmującą dwa argumenty:
int mnozenie(int liczba1, int liczba2) {
return liczba1 * liczba2;
}Możemy ją oczywiście w prosty sposób przetestować:
#include <iostream>
using namespace std;
int mnozenie(int liczba1, int liczba2) {
return liczba1 * liczba2;
}
int main() {
cout << mnozenie(2,2); //otrzymamy wynik: 4
return 0;
}Jak widać wszystko działa poprawnie. Ale co jeśli nie znamy liczby liczb, które chcemy pomnożyć? Aby rozwiązać ten problem musimy wprowadzić drobne modyfikacje:
int mnozenie(int liczba1, ...) {
va_list arg;
int iloczyn = 1;
int tmp = liczba1;
va_start(arg, liczba1);
while(tmp != 0) {
iloczyn *= tmp;
tmp = va_arg(arg, int);
}
va_end(arg);
return iloczyn;
}Oczywiście przy nieznanej liczbie argumentów, zawsze musimy wiedzieć jaką wartość ma ten podawany na początku oraz samym końcu ponieważ musimy w odpowiednim momencie zakończyć wykonywanie pętli aby nie dopuścić do błędu.
Jak widać na powyższym przykładzie listę argumentów będziemy przechowywać w obiekcie va_list nazwaListy; natomiast przegląd wszystkich argumentów rozpoczynamy uruchamiając funkcję va_start(nazwaListy, pierwszyArgument);. Poszczególne dane odczytywane są za pomocą funkcji va_arg(nazwaListy, typDanych);. Warto jeszcze wspomnieć że na końcu wymagane jest zamknięcie naszej listy za pomocą va_end(nazwaListy);.
Podana wyżej funkcja mnozenie() przyjmująca n argumentów, będzie mnożyć podane liczby do momentu wystąpienia 0:
#include <iostream>
using namespace std;
int mnozenie(int liczba1, ...) {
va_list arg;
int iloczyn = 1;
int tmp = liczba1;
va_start (arg, liczba1);
while(tmp != 0) {
iloczyn *= tmp;
tmp = va_arg(arg, int);
}
va_end (arg);
return iloczyn;
}
int main() {
cout << mnozenie(2, 2, 2, 3, 0); //wynik: 24
return 0;
}