direct способ для функции, которая использует va_arg
для определения количества или типов аргументов, переданных данным вызовом.
Ваш предложенный метод, в частности:
while(va_arg(argPtr, char) != NULL)
неверен. va_arg(argPtr, char)
дает значение типа char
, а NULL
- константа нулевого указателя. (NULL
обычно определяются как 0
, который сравнивает равно нулевой символ '\0'
, но вы не можете полагаться на это.)
Любой VARIADIC функция должна иметь способ для вызывающего абонента, чтобы указать количество и тип аргументов. Например, функции *printf
выполняют это посредством строки (невариантного) формата. Функции POSIX execl*()
ожидают последовательность аргументов char*
; конец списка аргументов отмечен вызывающим абонентом с (char*)NULL
. Другие методы возможны, но они почти все зависят от информации, заданной во время выполнения аргументов. (Вы можете использовать использовать какой-либо другой метод, такой как глобальная переменная. Пожалуйста, не делайте этого.)
Это накладывает нагрузку на вызывающего абонента, чтобы гарантировать, что аргументы, переданные функции, являются согласованными. Сама функция не может подтвердить это. Неверные вызовы, например printf("%d\n", "hello")
или execlp("name", "arg1")
, есть не определено поведение.
Еще одна вещь: вы не можете использовать va_arg
с аргументом типа char
. Когда вы вызываете вариационную функцию, аргументы, соответствующие , ...
, являются , продвигаемые. Целочисленные аргументы типов, более узкие, чем int
, составляют int
или unsigned int
, а аргументы типа float
- double
. Если вызывающий объект передает аргумент типа char
, функция должна вызывать va_arg(argPtr, int)
.
(в очень неясных обстоятельствах, которые вы, вероятно, столкнется, char
может быть повышенно до unsigned int
нет. Это может произойти только тогда, когда обычная char
беззнаковая и sizeof (int) == 1
, что означает, что байты по меньшей мере, 16 бит).
если 'n' является строка формата, то вы обычно просто вести себя как' printf' и семьи путем сопоставления числа спецификаторов формата от числа параметров. Вы уверены, что это просто переменная часть 'char' передается? Если это так, вы можете сопоставлять «-1» или «0» или что-то в этом роде, но NULL - это плохая идея по причинам, изложенным в @hvd в его комментариях ниже. –
@kekyc, если вы полагаетесь на отрицательные значения 'char', тогда вы должны использовать' signed char', если вы имеете дело только со значениями в диапазоне [0, 128] (ascii), тогда -1 должно быть хорошо. –
Если вы передаете список аргументов 'char' переменной длины, почему бы просто не передать строку? (Есть * некоторые * случаи, когда это не сработало, но это очевидное решение.) –