Russian Belarusian English German Japanese Ukrainian
  • Главная
  • Передача в функции переменного числа параметров

3.55

Иногда в функции требуется передавать некоторое число фиксированных параметров плюс неопределенное число дополнительных параметров. В этом случае заголовок функции имеет вид:

тип имя_функции(список аргументов,...)

В данном случае список аргументов включает в себя конечное число обязательных аргументов (этот список не может быть пустым), после которого ставится многоточие на месте неопределенного числа параметров. Для работы с этими параметрами в файле stdarg.h определен тип списка va_list и три макроса: va_start, va_arg и va_end.

Макрос va_start имеет синтаксис:

void va_start(va_list ap, lastfix)

Этот макрос начинает работу со списком, устанавливая его указатель ар на первый передаваемый в функцию аргумент из списка с неопределенным числом аргументов. Параметр lastfix - это имя последнего из обязательных аргументов функции.

Макрос va_arg имеет синтаксис: typeva_arg(va_listар, type) Макрос возвращает значение очередного аргумента из списка. Параметр type указывает тип аргумента. Перед вызовом va_arg значение ар должно быть установлено вызовом va_start или va_arg. Каждый вызов va_arg переводит указатель ар на следующий аргумент.

Макрос va_end имеет синтаксис:

void va_end(va_list ap)

Макрос завершает работу со списком, освобождая память. Он должен вызываться после того, как с помощью va_arg прочитан весь список аргументов. В противном случае могут быть непредсказуемые последствия.

Рассмотрим пример. Пусть требуется создать функцию average, которая рассчитывает и отображает в метке Label1 среднее значение передаваемых в нее целых положительных чисел. Функция принимает в качестве первого аргумента некоторое сообщение, которое должно отображаться перед результатами расчета. Список обрабатываемых чисел может быть любой длины и заканчиваться нулем. Такая функция может быть реализована следующим образом:

#include<stdarg.h>
void average(AnsiString mess,...) {
double A=0;
int i=0,arg;
va_list ap;
va_start(ap, mess);
while ((arg = va_arg (ap,int)) != 0) {
i++;
A += arg;
}
Form1->Label1->Caption = mess + "N= " +IntToStr(i) + ", среднее= "+FloatToStr(A/i);
va_end(ap);
}

Вызов функции может быть, например, таким:

average("Результаты экзамена: ",4,2,3,5,4,0);

В результате функция выдаст в метку Label1 сообщение:

Результаты экзамена: N = 5, среднее = 3,6

Функцию average можно было бы организовать иначе, не вводя специальную конечную метку в список (в приведенном примере - 0), а предваряя список аргументов параметром N, указывающим размер списка:

void average(AnsiStгinq mess, int N,..)
{
double A=0;
va_list ар;
va_start(ар, N);
for(int i=0; i<N; i + +)
A += va_arg(ap,int);
Form1->Label1->Caption = mess + "N = " +IntToStr(N) + ", среднее= "+FloatToStr(A/N);
va_end(ap);
}

Вызов функции может быть, например, таким:

average("Результаты экзамена: ",5,4,2,3,5,4);

Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter

Добавить комментарий


Поиск по сайту