628_____________________________________________Глава 11

Этот пример показывает, что последними в списке параметров со значениями
по умолчанию надо указывать те параметры, значения которых в реальных зада-
чах чаще всего остаются равными заданным по умолчанию.

Пропускать при вызове можно только некоторое число последних параметров
в списке. Например, нельзя вызвать функцию таким образом:

F = Arh(2,,l.l); // Ошибочный вызов

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

11.5.5 Передача в функции переменного числа параметров

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

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

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

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

void va_start(va_list ар, lastfix)

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

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

type va arg(va_list ар, type)

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

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

void va end(va_list ар)

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

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

#include <stdarg.h>

void average(AnsiString mess,...)
{

double A = 0;

int i = 0,arg;

va list ap;