How does printf handle its arguments? I know that in C# I can use params
keyword to do something similar but I can't get it done in C ?
views:
320answers:
5The way this is done in C is called "varargs". There's a tutorial for it here: http://c-faq.com/~scs/cclass/int/sx11b.html
Such a function is called a variadic function. You may declare one in C using ...
, like so:
int f(int, ... );
You may then use va_start
, va_arg
, and va_end
to work with the argument list. Here is an example:
#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));
}
For more information, please see The C Book and stdarg.h.
This feature is called Variable numbers of arguments in a function. You have to include stdarg.h header file; then use va_list type and va_start, va_arg, and va_end functions within the body of your function:
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);
}
Then call your function like this:
print_arguments(3,1,2,3);
which will print out following:
I am first element of the list: 1
I am second element of the list: 2
I am third element of the list: 3
Like others have said, printf uses va_args to function. It's a pretty cool exercise to write your own version of printf, if nothing else to verify that printf, unlike Pascal's writeln is not compiler magic. After you do that, you should walk away from it. Here is a blog article I wrote detailing why (the short answer is you can create bugs that may go undetected for a long time).
and just to complete the story gcc (not sure about other compilers) supports
#define FUNC(X,Y,...) wiz(X,Y, ##__VA_ARGS__)
to allow variadic macros