Interested Article - Вариативная функция

В программировании функции с переменным числом аргументов называются вариативными.

Существует множество математических и логических операций, которые лучше реализовать с помощью функций с переменным количеством аргументов, например, суммирование чисел или конкатенация строк.

Пример в Си

Для реализации функций с переменным числом аргументов в языке программирования 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 в Си определяется конкретной реализацией и не обязан быть нулём, приведённым к типу void * , а в C++ определён как 0 без явного приведения к указателю. Число 0 имеет тип int , минимальный размер которого соответствует 16 битам (2 байта), что, скорее всего, будет не соответствовать размеру ожидаемого в функции указателя.

stdarg.h объявляет тип va_list , и определяет четыре макрофункции : va_start , va_arg , va_copy и va_end .

  1. va_start принимает два аргумента, объект va_list и ссылку на последний параметр функции (тот, что перед многоточием). Она инициализирует va_list объект для использования в va_arg или va_copy . Компилятор обычно выдает предупреждение, если ссылка неверная (например, ссылка на параметры, отличающиеся от последнего, или ссылка на совершенно другой объект).
  2. va_arg принимает два аргумента, va_list объект (ранее инициализированный) и дескриптор типа. Он расширяется на следующей переменной аргумент, и имеет указанный тип. Каждый следующий вызов возвращает следующий аргумент.
  3. va_end принимает один аргумент типа va_list и очищает его. Если вы хотели, например, сканировать переменное число аргументов более чем один раз, вам надо будет повторно инициализировать va_list путём вызова va_end и затем va_start .
  4. va_copy принимает два аргумента, оба типа va_list . Он дублирует второй (который должен был быть инициализирован) в первый.

См. также

Примечания

  1. . Дата обращения: 13 февраля 2016. 31 октября 2012 года.

Ссылки

  • . Rosetta Code task showing the implementation of variadic functions in over fifty programming languages.
  • — A tutorial on Variable Argument Functions for C++
Источник —

Same as Вариативная функция