Вызов функцииФункции с переменным количеством параметров - часть 3
puts(ss); // Вывод строки по указателю
break;
}}}}
Этот механизм может быть скрыт от программиста соответствующими макрокомандами.
//------------------------------------------------------bk45-02.cpp
#include <stdarg.h>
int printf(char *s,...)
{
va_list PNT; // Аналог указателя на область стека
int ii;
double dd;
char *ss;
va_start(PNT,s+1); // Назначить указатель на начало
while (*s != '\0') // Просмотр форматной строки
{
if (*s != '%')
putchar(*s++); // Копирование форматной строки
else
{ s++; // Спецификация параметра вида "%d"
switch(*s++)
{ // Извлечение параметра по указателю
// и переход к следующему
case 'd': ii = va_arg(PNT,int);
break; // Преобразование и вывод целого
case 'f': dd = va_arg(PNT,double);
// Преобразование и вывод плавающего
break;
case 's': ss = va_arg(PNT, char*);
puts(ss); // Вывод строки по указателю
break;
}
}}
va_end(PNT);
}
Макрокоманда va_list определяет переменную -указатель на область параметров в стеке, va_start назначает его на область памяти, расположенную за последним явно указанным параметром, va_arg извлекает из памяти переменную указанного типа и продвигает указатель на ее размерность, va_end выполняет завершающие действия. Использование макрокоманд предпочтительнее, так как они учитывают все нюансы механизма передачи параметров в данной версии транслятора (например, выравнивание адреса параметра к границе машинного слова ).