ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4304
Скачиваний: 28
Часть III. Стандартная библиотека языка программирования C
306
В листинге 22.1 приведен пример использования макрокоманды
assert
. При запуске этой программы в поток
stderr
запишется
подобное сообщение:
Assertion failed: n < 0, file C:\test\main.cpp, line 7
После отладки программы макрокоманду
assert
можно не уда-
лять из исходного текста, а просто отменить ее определение. Для
того нужно определить символическое имя
NDEBUG
. Причем
это имя должно быть объявлено перед директивой
#include
<assert.h>
.
Листинг 22.1. Использование макрокоманды
assert
#include <assert.h>
int main()
{
int n = 10;
assert(n > 0);
assert(n < 0);
return 0;
}
Г Л А В А
23
Функции
с переменным количеством
параметров <stdarg.h>
В языке программирования С допускается использование функ-
ций с переменным количеством параметров. В этом случае в кон-
це списка параметров ставится многоточие
...
При этом предпо-
лагается, что в списке параметров присутствует хотя бы один па-
раметр.
Например, можно определить функцию для сложения произволь-
ного количества целых чисел следующим образом:
int add_num(int n, ...); /* n - количество слагаемых */
Также, в качестве примеров функций с переменным количеством
параметров, можно назвать стандартные функции
scanf
и
printf
.
Для обработки функций с переменным количеством параметров
в заголовочном файле
stdarg.h
определен тип данных
va_list
и
три макроса
va_start
,
va_arg
и
va_end
.
Тип данных
va_list
обычно определяется следующим образом:
typedef char* va_list;
Этот тип служит для объявления указателя, в который макросы
va_start
и
va_arg
записывают адреса аргументов из вызова функ-
ции с переменным количеством параметров.
Макрос
va_start
выполняет инициализацию переменной типа
va_list
, необходимую для доступа к аргументам, для которых не
Часть III. Стандартная библиотека языка программирования C
308
объявлены параметры в функции с переменным количеством па-
раметров. Этот макрос определен следующим образом:
#define va_start(ap, v) void_выражение
Параметр
ap
обозначает имя переменной типа
va_list
, в которую
макрокоманда помещает адрес последнего заданного аргумента в
вызове функции; параметр
v
обозначает имя этого последнего
заданного аргумента в вызове функции; а
void_выражение
пред-
ставляет реализацию макрокоманды и зависит от системы.
На тип последнего заданного аргумента в функции с перемен-
ным количеством параметров накладываются следующие огра-
ничения:
не допускается спецификатор класса памяти
register
;
не допускается тип "функция";
не допускается тип "массив";
не допускается тип, который не сравним с типом, полученным
после интегрального продвижения по типам.
Если эти ограничения не выполняются, то результат работы мак-
рокоманды
va_start
не определен.
Макрос
va_arg
используется для последовательного доступа к
аргументам функции с переменным количеством параметров.
Этот макрос определен следующим образом:
#define va_arg(ap, t) t_выражение
Параметр
ap
обозначает имя переменной, которая была инициа-
лизирована макрокомандой
va_start
; параметр
t
обозначает тип
аргумента в вызове функции, значение которого нужно получить;
а
t_выражение
представляет реализацию макрокоманды. Результа-
том вычисления
t_выражения
является R-value типа
t
, значение
которого равно значению следующего аргумента. Если следую-
щего аргумента нет, то результат работы макрокоманды непред-
сказуем.
Макрос
va_end
используется после завершения работы с аргумен-
тами функции с переменным количеством параметров. Назначе-
ние этой макрокоманды обеспечить правильную работу инструк-
Глава 23. Функции с переменным количеством параметров <stdarg.h> 309
ции
return
в функции с переменным количеством параметров.
Определена макрокоманда
va_end
следующим образом:
#define va_end(ap) void_выражение
Параметр
ap
обозначает имя переменной, которая была инициа-
лизирована макрокомандой
va_start
, а
void_выражение
представ-
ляет реализацию макрокоманды.
В листинге 23.1 приведен пример реализации функции с пере-
менным количеством параметров
. Эта функция просто рас-
печатывает свои аргументы, которые являются целыми числами.
Листинг 23.1. Функция с переменным количеством параметров
#include <stdio.h>
#include <stdarg.h>
int print(short n, ...)
{
va_list a;
if (n < 1) /* проверяем, есть ли параметры */
{
printf("There are no numbers.\n");
return 0;
}
printf("Number of parameters = %d\n", n);
va_start(a, n); /* инициализируем a */
while (n--) /* распечатываем аргументы */
{
int x;
x = va_arg(a, int); /* получаем следующий аргумент */
printf("%d\n", x); /* распечатываем аргумент */
}
va_end(a); /* завершение продвижения по аргументам */
return 0;
}
/* проверяем работу функции print */
int main()
{
print(0);
Часть III. Стандартная библиотека языка программирования C
310
print(1, 1);
print(2, 10, 20);
print(3, 100, 200, 300);
return 0;
}