Sunday 21 April 2013

Functions with a Variable Number of Parameters

Functions can be written which can take any number of parameters. It is now possible to
write your own equivalent of printf1. To write functions with a variable number of
parameters it is necessary to use the macros, va_start and va_end, which are defined in
the header file, stdarg.h. Individual unnamed parameters can be obtained with the
va_arg macro, or the vprintf range of print routines can be used to print a list of
unnamed parameters.
The first of the following examples uses vfprintf to print the unnamed parameters, the
second extracts the unnamed parameters one by one using va_arg.
#include <stdio.h> // for fprintf
#include <stdlib.h> // for exit
#include <stdarg.h> // for variable num of args macros
void error(char *format ...)
{
va_list args;
va_start(args, format);
// make args point to first unnamed parameter
fprintf(stderr, "ERROR: ");
// print start of error message
vfprintf(stderr, format, args);
// print all unnamed arguments
fprintf(stderr, "\n");
// move onto newline
va_end(args);
// tidy up
exit(1);
// return to OS with exit status of 1
}
int main()
{
int i = -1;
error("invalid value %d encountered", i);
return 0;
}
But you shouldn't! Use operator<< instead
#include <stdio.h>
#include <stdarg.h>
void sum(char *message ...)
{
int total = 0;
va_list args;
int arg;
va_start(args, message);
while ((arg = va_arg(args, int)) != 0)
total += arg;
printf(message, total);
va_end(args);
}
int main()
{
sum("The total of 1+2+3+4 is %d\n", 1, 2, 3, 4, 0);
return 0;
}
We must make sure that the function knows which is the last actual parameter, otherwise
we may try to remove too many parameters from the stack. In the first example, we used the
vfprintf function, which is the printf function to use in conjunction with a variable
number of arguments. Like printf, the number of conversion characters must match the
number of extra parameters. In the second example a special trailing value is used to
indicate the last parameter.
In ANSI C the parameter list is written
func(named parameters, ...)
That is a comma precedes the ellipsis (...).

No comments:

Post a Comment