У програмуванні, фу́нкції зі змі́нним число́м аргуме́нтів називають варіативними.
Існує багато математичних і логічних операцій, які краще реалізувати за допомогою функцій зі змінною кількістю аргументів, наприклад, підсумовування чисел або конкатенація рядків.
Приклад у C Для реалізації функцій зі змінним числом аргументів у мові програмування C потрібно підключити заголовний файл stdarg.h. Раніше використовувався varargs.h, який оголошено застарілим. Для C++ цей заголовний файл називається cstdarg. #include <stdarg.h>
double average(int count, ...) { va_list ap; int j; double sum = 0;
va_start(ap, count); /* Потрібен останній відомий аргумент (щоб отримати адресу першого невідомного) */ for (j = 0; j < count; j++) { sum += va_arg(ap, double); /* Збільшує ap до наступного аргументу. */
va_end(ap);
return sum / count; }Ця функція дозволяє обчислити середнє значення від довільної кількості аргументів. Зверніть увагу, що функція не знає числа аргументів і їх типів. Функція з прикладу вище очікує, що типи будуть double і що число параметрів передається першим аргументом. В інших випадках, наприклад для функції printf(), число і типи аргументів з'ясовуються за рядком формату.
У загальному випадку варто знати про правило підвищення типів за замовчуванням, за яким підвищення типів зазнають усі аргументи функції, включно з невідомими аргументами. Так, якби в прикладі вище невідомі аргументи були оголошені типу float, фактично вони б виявилися типу double, і очікувати функція мала б тип double, а не float. Це може спричинити плутанину й помилки, якщо функція очікує аргумент певного розміру, а отримує аргумент іншого розміру. Особливо небезпечним є використання макроса NULL у варіативних функціях, оскільки NULL у C визначається конкретною реалізацією і не зобов'язаний бути нулем, зведеним до типу void *, а в C++ визначений як 0 без явного зведення до вказівника. Число 0 має тип int, найменший розмір якого відповідає 16 бітам (2 байти), що, найпевніш, не відповідатиме розміру очікуваного у функції вказівника.
stdarg.h оголошує тип va_list, і визначає чотири макрофункції: va_start, va_arg, va_copy і va_end. Кожному виклику va_start і va_copy має відповідати виклик va_end. Під час роботи зі змінним числом аргументів функція зазвичай оголошує змінну типу va_list (ap у прикладі), якою маніпулюватимуть макроси.
va_start приймає два аргументи: об'єкт va_list і посилання на останній параметр функції (той, що перед трикрапкою). Вона ініціалізує об'єкт va_list для використання у va_arg або va_copy. Компілятор зазвичай виводить попередження, якщо посилання хибне (наприклад, посилання на параметри, що відрізняються від останнього, або посилання на зовсім інший об'єкт). va_arg приймає два аргументи: об'єкт va_list (раніше ініціалізований) і дескриптор типу. Він розширюється на наступний аргумент і має вказаний тип. Кожен наступний виклик повертає наступний аргумент. va_end приймає один аргумент типу va_list і очищає його. Якщо потрібно, наприклад, опрацювати змінне число аргументів більш ніж один раз, слід повторно ініціалізувати va_list, викликавши va_end і потім va_start. va_copy приймає два аргументи, обидва типи va_list. Він дублює другий (який повинен був бути ініціалізованим) у перший.
Приклад у Odin Функцій зі змінним числом аргументів у мові програмування Odin доступні відразу з стандартної бібліотеки.import "core:fmt"
sum :: proc(nums: ..int) -> (result: int) { for n in nums { result += n } return }
main :: proc() { fmt.println(sum()) // 0 fmt.println(sum(1, 2)) // 3 fmt.println(sum(1, 2, 3, 4, 5)) // 15
odds := []int{1, 3, 5} fmt.println(sum(..odds)) // 9, передаємо масив як набір аргументів } Див. також Варіативний макрос (мова програмування C) Варіативний шаблон
Примітки
Посилання Variadic function — задача Rosetta Code, що показує реалізацію варіативних функцій у більш ніж п'ятдесяти мовах програмування. Variable Argument Functions — посібник про функції зі змінним числом аргументів у C++ GNU libc manual