В конце списка формальных параметров функции могут быть записана запятая и многоточие. Это означает, что число аргументов функции переменно, но не меньше, чем число имен типов, заданных до многоточия.
Если список типов аргументов содержит только многоточие, то число аргументов функции является переменным и может быть равным нулю.
В списке типов аргументов в качестве имени типа допускается также конструкция void *, которая специфицирует аргумент типа "указатель на любой тип". Для доступа к переменному списку параметров можно использовать указатели.
Приведенная ниже функция с переменным числом аргументов используется для записи кодов клавиш в собственный буфер клавиатуры.
#define KEY unsigned int
#define MAX_BUF 9
static KEY Buf [MAX_BUF];
KEY Start = 0;
void Set_Key(KEY kol,...) {
//Параметр kol задает
//количество остальных параметров
KEY *ptr; //Указываем на первый символ
ptr = &kol; //в строке параметров
for(; kol!= 0; kol--) {
Buf [Start++] = *++ptr;
//Последовательно записываем символы
Start %= MAX_BUF;
//во внутренний буфер с контролем
|
|
//его переполнения
}
return;
}
Предполагается, что полные двухбайтовые коды клавиш определены в заголовочном файле:
#define ENTER 0x000D
#define END 0x4F00
#define RIGHT 0x4d00
Тогда функция может быть вызвана, например, так:
Set_Key (1,ENTER);
Set_Key (2,END,RIGHT);
В дальнейшем функция получения кодов символов может извлекать ранее записанные символы следующим образом:
#define MODE unsigned char
KEY Get_Key (void) {
KEY sim;
MODE scan,ascii;
if (Start!= End) {
sim = Buf [End++]; End %= MAX_BUF;
}
else {
asm MOV AH,0x00;
asm INT 16H;
sim=_AX; //или вызов bioskey (0);
scan=(MODE)((sim&0xff00)>>8); //_AH
ascii=(MODE)(sim&0x00ff); //_AL
if (ascii) scan=0;
sim=(scan<<8)+ascii;
}
return (sim);
}
Здесь инструкция asm позволяет выполнить ассемблерный код непосредственно из программы на Си. Инструкция разрешает выполнять и блок ассемблерных команд: asm { }. Существует также библиотека stdarg.h для работы с переменными списками аргументов.