Как printf обрабатывает свои аргументы?
Как printf обрабатывает свои аргументы? Я знаю, что в С# я могу использовать ключевое слово params
, чтобы сделать что-то подобное, но я не могу сделать это в C?
Ответы
Ответ 1
Такая функция называется вариационной функцией. Вы можете объявить один в C с помощью ...
, например:
int f(int, ... );
Затем вы можете использовать va_start
, va_arg
и va_end
для работы с списком аргументов. Вот пример:
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
void f(void);
main(){
f();
}
int maxof(int n_args, ...){
register int i;
int max, a;
va_list ap;
va_start(ap, n_args);
max = va_arg(ap, int);
for(i = 2; i <= n_args; i++) {
if((a = va_arg(ap, int)) > max)
max = a;
}
va_end(ap);
return max;
}
void f(void) {
int i = 5;
int j[256];
j[42] = 24;
printf("%d\n",maxof(3, i, j[42], 0));
}
Для получения дополнительной информации см. C Book и stdarg.h.
Ответ 2
То, как это делается в C, называется "varargs". Там учебник для этого здесь: http://c-faq.com/~scs/cclass/int/sx11b.html
Ответ 3
Эта функция называется переменным числом аргументов в функции. Вы должны включить заголовочный файл stdarg.h; затем используйте va_list и va_start, va_arg и va_end в теле вашей функции:
void print_arguments(int number_of_arguments, ...)
{
va_list list;
va_start(list, number_of_arguments);
printf("I am first element of the list: %d \n", va_arg(list, int));
printf("I am second element of the list: %d \n", va_arg(list, int));
printf("I am third element of the list: %d \n", va_arg(list, int));
va_end(list);
}
Затем вызовите свою функцию следующим образом:
print_arguments(3,1,2,3);
который будет распечатываться следующим образом:
I am first element of the list: 1
I am second element of the list: 2
I am third element of the list: 3
Ответ 4
Как и другие, printf использует va_args для работы. Это довольно крутое упражнение, чтобы написать собственную версию printf, если ничего другого не проверить, что printf, в отличие от Pascal writeln, не является маской компилятора. После этого вы должны уйти от него. Вот статья блога Я написал подробное объяснение, почему (краткий ответ: вы можете создавать ошибки, которые могут оставаться необнаруженными в течение длительного времени).
Ответ 5
и просто для завершения истории gcc (не уверен в других компиляторах) поддерживает
#define FUNC(X,Y,...) wiz(X,Y, ##__VA_ARGS__)
чтобы позволить переменные макросы