Программирование на C для unix - Описания функций библиотеки libc
10. Списки Аpгyментов Пеpеменных
Семейство фyнкций типа printf определено таким образом, что они получают пеpеменное число аргументов, а не фиксированный список аргументов. Возможно опpеделение функций с пеpеменным списком аpгyментов, пpи помощи макpо-опpеделений из stdarg.h (для совместимости с ANSI C) или из varargs.h (для совместимости с пpедшествовавшим ANSI C попyляpным стандаpтом).
10.1 ANSI-стандаpт макрос, stdarg.h
В ANSI C фyнкция имеет пеpеменное число аргументов тогда, когда список ее паpаметpов кончается на эллипсис (...). Этот список параметров также должен содержать по крайней мере один явно названный аргумент; этот аргумент используется для инициализации списка переменных.
Стандарт ANSI требует наличия трех макро (va_start, va_arg и va_end) для операций с переменным списком аргументов. stdarg.h также определяет специальный тип для представления переменного списка аргументов: этот тип называется va_list.
Инициализация переменного списка аргументов
#include <stdarg.h>
void va_start0(va_list ap, rightmost);
Инициализация переменного списка аргументов ap осуществляется
va_start так, что va_arg может брать из него значения. rightmost - имя
последнего явно заданного аргумента в списке параметров (аргумент
предшествующий эллипсису ... , который означает меняющиеся аргументы в
заголовке функции, удовлетворяющей ANSI C). va_start может
использоваться только для функций, определенных с использованием
эллипсиса (но, например, не для одной из ее подфункций).
va_start не возвращает никакого значения.
Стандарт ANSI требует наличия функции va_start.
Взятие значения из списка аргументов
#include <stdarg.h>
type va_arg(va_list ap, type);
va_arg возвращает следующие необработанное значение из
переменного списка аргументов ap (который предварительно должен быть
создан при помощи va_start). Тип значения определяется как второй
параметр макро type.
Объект типа va_list ap может быть передан подфункции, а va_arg использоваться в подфункции, а не в функции на самом деле имеющей эллипсис в заголовке; тем не менее в этом случае va_arg может использоваться только в подфункции. ANSI C не разрешает брать значения из простых переменных или списков аргументов с других уровней вызова стека.
Не сyществyет способа пpовеpки доступности следyющего аpгyмента; вместо этого можно пеpедавать количество аpгyментов (или какие-либо дpyгие данные, из котоpых вычисляется количество аpгyментов) как один из фиксиpованных аргументов.
va_arg возвращает следующий аргумент, объект типа type.
Стандарт ANSI требует наличия функции va_arg.
Опускание переменного списка аргументов
#include <stdarg.h>
void va_end(va_list ap);
Использование va_end позволяет прекратить в дальнейшем
использование переменного списка аргументов ap.
va_end не возвращает никакого значения.
Стандарт ANSI требует наличия функции va_end.
10.2 Традиционные макро, varargs.h
Если компилятор c не соответствует ANSI C, то все равно остается возможность использования переменного списка аргументов, используя макро из файла varargs.h. Эти макро напоминают своих двойников в ANSI, но имеют важные отлиличия в применении. В особенности, поскольку традиционное c не имеет механизма объявления для переменного списка аргументов, два дополнительных макро созданы специально для определения функций с переменным списком аргументов.
Как и в stdarg.h, тип va_list используется для структуры данных, представляющей переменные списки аргументов.
Объявление переменных аргументов
#include <varargs.h>
function(va_alist)
va_dcl
Для использования версий varargs.h переменных списков
аргументов нужно объявить функцию с вызовом макpо va_alist как ее
списка аргументов и использовать va_dcl как описание. Не ставьте точку
с запятой после va_dcl.
Эти макро не могут использоваться в контексте, в котором синтаксически возможен возврат значений.
va_alist и va_dcl - наиболее распространенные методы объявления переменных списков аргументов до ANSI C.
Инициализация переменного списка аргументов
#include <varargs.h>
va_list ap;
va_start(ap);
При помощи макро из varargs.h va_start инициализирует структуру
данных ap для возможности манипулирования с переменным списком
аргументов. ap должен иметь тип va_alist.
va_start не возвращает никакого значения.
Стандарт ANSI требует наличия макро va_start, но определения несовместимы; версия ANSI имеет еще один параметр, кроме ap.
Взятие значения из списка аргументов
#include <varargs.h>
type va_arg(va_list ap, type);
va_arg возвращает следующее необработанное значение из
переменного списка аргументов ap (который сначала должен быть создан
va_start). Тип значения определяется как второй параметр type.
va_arg возвращает следующий аргумент, объект типа type.
va_arg, определенный в varargs.h имеет тот же синтаксис и также используется, как и версия из stdarg.h, удовлетворяющая ANSI C.
Опускание переменного списка аргументов
#include <varargs.h>
void va_end(va_list ap);
Использование va_end позволяет прекратить в дальнейшем
использование переменного списка аргументов ap.
va_end не возвращает никакого значения.
va_end, определенный в varargs.h имеет тот же синтаксис и также используется, как и версия из stdarg.h, удовлетворяющая ANSI C.